Introduction
Most of compilers use PostFix to generat native code. For more information about PostFix, refer here.
I want to talk about a simple code in C# to preception it.
Using the code
The program is under Console. The operands have to be one digit numbers in this program. Here the main code:
static void Main(string[] args)
{
string inFix, postFix = string.Empty;
while (true)
{
Console.Write("Enter InFix Expression: ");
inFix = Console.ReadLine().Replace(" ", string.Empty);
if (IsValid(inFix)) {
Console.WriteLine("\nPostFix: {0}",ConvertToPostFix(inFix));
break;
}
Console.WriteLine("\nNot a valid Epression!\n");
}
Console.ReadKey();
}
All right, I used some methods and wanted to declare them.
Declaring ConvertToPostFix:
private static string ConvertToPostFix(string inFix)
{
StringBuilder postFix = new StringBuilder();
char arrival;
Stack<char> oprerator = new Stack<char>(); foreach (char c in inFix.ToCharArray()) {
if (Char.IsNumber(c))
postFix.Append(c);
else if (c == '(')
oprerator.Push(c);
else if (c == ')') {
arrival = oprerator.Pop();
while (arrival != '(')
{
postFix.Append(arrival);
arrival = oprerator.Pop();
}
}
else
{
if (oprerator.Count != 0 && Predecessor(oprerator.Peek(), c)) {
arrival = oprerator.Pop();
while (Predecessor(arrival, c))
{
postFix.Append(arrival);
if (oprerator.Count == 0)
break;
arrival = oprerator.Pop();
}
oprerator.Push(c);
}
else
oprerator.Push(c); }
}
while (oprerator.Count > 0)
{
arrival = oprerator.Pop();
postFix.Append(arrival);
}
return postFix.ToString();
}
In this code if user enters 12+3-55+c
, it will raise error for 12
and c
. Because it's a simple program and compares characters one by one. They sould be numeric. The best input is an expression like this: (9*(1-3))-4*(3+3*4)
and the result will be: 913-*4334*+*-
Comparing the precedences:
private static bool Predecessor(char firstOperator, char secondOperator)
{
string opString = "(+-*/%";
int firstPoint, secondPoint;
int[] precedence = { 0, 12, 12, 13, 13, 13 };
firstPoint = opString.IndexOf(firstOperator);
secondPoint = opString.IndexOf(secondOperator);
return (precedence[firstPoint] >= precedence[secondPoint]) ? true : false;
}
Clear!
Validation Mehod:
Private static bool IsValid(string input)
{
Regex operators = new Regex(@"[\-+*/%]", RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);
if (string.IsNullOrEmpty(input))
return false;
if (input.ToCharArray().Select(c => c == '(').Count() != input.ToCharArray().Select(c => c == ')').Count())
return false;
string tempString = operators.Replace(input, ".");
if (tempString.EndsWith("."))
return false;
string[] contains = new string[] { "(.)", "()", "..", ".)" };
foreach (string s in contains)
{
if (tempString.Contains(s))
return false;
}
operators = new Regex(@"[().]", RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);
tempString = operators.Replace(tempString, string.Empty);
foreach (char c in tempString.ToCharArray())
{
if (!Char.IsNumber(c))
return false;
}
if (input.Contains("."))
return false;
tempString = input;
operators = new Regex(@"[1234567890]", RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);
tempString = operators.Replace(tempString, ".");
if (tempString.Contains(".."))
return false;
if (input.StartsWith("*") || input.StartsWith("/") || input.StartsWith("%")
|| input.StartsWith("+") || input.StartsWith("-"))
return false;
contains = new string[] {"(%","(/","(*","*","(+","(-" };
foreach (string s in contains)
{
if (input.Contains(s))
return false;
}
int begin = 0, end = 0;
foreach (char c in input)
{
if (c == '(')
begin++;
if (c == ')')
end++;
if (end > begin)
return false;
}
return true;
}
(Thanks to OriginalGriff for some advising)
Validation method, unlike its harash exterior, works easy.
It checks all parenthesis:
- Number of "(" and ")" if doesn't match, returns false.
- If for example: ((1+3)))(, return's false
- if "*1" or "/5" or "%9" or ...
- if "(+" or "(-" or ...
- ...
And for all invalid expression, returns false
.