65.9K
CodeProject is changing. Read more.
Home

Parsing a postfix expression in C#, my naive approach

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5 votes)

Nov 22, 2010

CPOL
viewsIcon

16114

Here is my take on the same, using Lambda expressions and slightly more advanced regular expression features:I have not tested this code, so errors may exist.This implementation will ignore unrecognized tokens. namespace Postfix { class Parser { static Dictionary<string,...

Here is my take on the same, using Lambda expressions and slightly more advanced regular expression features: I have not tested this code, so errors may exist. This implementation will ignore unrecognized tokens.
	namespace Postfix
	{
		class Parser
		{
			static Dictionary<string, Func<int, int, int>> operators;
			static Regex parserEngine = new Regex(@"\G(\s+(?<op>[-+*/])|\s*(?<value>-?[0-9]+))", RegexOptions.ExplicitCapture);

			static Parser()
			{
				operators = new Dictionary<string, Func<int, int, int>>();
				operators["+"] = (a, b) => a + b;
				operators["-"] = (a, b) => a - b;
				operators["*"] = (a, b) => a * b;
				operators["/"] = (a, b) => a / b;
			}

			static int parseExp(string s)
			{
				Stack<int> stack = new Stack<int>();
				
				foreach(Match match in parserEngine.Matches(s))
				{
					if(match.Success)
					{
						foreach(KeyValuePair<string, string> m in match.Groups)
						{
							if(m.Key == "op")
							{
								if(stack.Count < 2)
									throw new Exception("Invalid expression: out of stack.");
								int b = stack.Pop();
								int a = stack.Pop();
								stack.Push(operators[m.Value](a, b));
							}
							else if(m.Key == "value")
								stack.Push(int.Parse(m.Value));
						}
					}
				}

				if(stack.Count != 1)
					throw new Exception("Invalid expression: not exactly one result on stack.");

				return stack.Pop();
			}

			static void Main()
			{
				string exp = "23 5 - 12 *";
				Console.WriteLine("expression '{0}' result is '{1}'", exp, Parser.parseExp(exp));
			}
		}
	}