static IElement Parse(IReadOnlyList <Token> tokens) { var result = new BinaryOperation(); bool haveLHS = false; for (int i = 0; i < tokens.Count; i++) { var token = tokens[i]; switch (token.MyType) { case Token.Type.Integer: var integer = new Integer(int.Parse(token.Text)); if (!haveLHS) { result.Left = integer; haveLHS = true; } else { result.Right = integer; } break; case Token.Type.Plus: result.MyType = BinaryOperation.Type.Addition; break; case Token.Type.Minus: result.MyType = BinaryOperation.Type.Subtraction; break; case Token.Type.Lparen: int j = i; for (; j < tokens.Count; ++j) { if (tokens[j].MyType == Token.Type.Rparen) { break; } } var subexpression = tokens.Skip(i + 1).Take(j - i - 1).ToList(); var element = Parse(subexpression); if (!haveLHS) { result.Left = element; haveLHS = true; } else { result.Right = element; } i = j; break; default: throw new ArgumentOutOfRangeException(); } } return(result); }
public int Calculate(string expression) { var tokens = Lex(expression); var lastToken = tokens[tokens.Count - 1]; if (lastToken.MyType == Token.Type.Unknown) { return(0); } var result = new BinaryOperation(); bool haveLHS = false; for (int i = 0; i < tokens.Count; i++) { var token = tokens[i]; switch (token.MyType) { case Token.Type.Integer: var integer = new Integer(int.Parse(token.Text)); if (!haveLHS) { result.Left = integer; haveLHS = true; } else { result.Right = integer; if (i < tokens.Count - 1) { result.Left = new BinaryOperation { Left = result.Left, Right = result.Right, OperationType = result.OperationType }; } } break; case Token.Type.Plus: result.OperationType = BinaryOperation.Type.Addition; break; case Token.Type.Minus: result.OperationType = BinaryOperation.Type.Subtraction; break; } } return(result.Value); }