private ExpressionToken ParseExpression(ExpressionToken lhs, TokenPriority priority) { while (true) { if (lhs.Type == TokenType.MinusOperator) { lhs = ParseExpression(UpcomingToken, TokenPriority.UnaryMinus); if (lhs is ValueToken) { lhs = -lhs; } else { throw new ArgumentException($"Unary minus is valid only for ValueToken!{lhs} is not a ValueToken"); } NextToken(); break; } else if (lhs.Type == TokenType.NotOperator) { lhs = ParseExpression(UpcomingToken, TokenPriority.Not); if (lhs is ValueToken) { lhs = !lhs; } else { throw new ArgumentException($"Unary minus is valid only for ValueToken!{lhs} is not a ValueToken"); } NextToken(); break; } break; } while (UpcomingToken is OperatorToken && (UpcomingToken as OperatorToken).Priority >= priority) { OperatorToken op = UpcomingToken as OperatorToken; NextToken(); ExpressionToken rhs = UpcomingToken; NextToken(); while (UpcomingToken is OperatorToken && (UpcomingToken as OperatorToken).Priority > op.Priority) { rhs = ParseExpression(rhs, (UpcomingToken as OperatorToken).Priority); NextToken(); } switch (op.Type) { case TokenType.PlusOperator: lhs = lhs + rhs; break; case TokenType.MinusOperator: lhs = lhs - rhs; break; case TokenType.DivideOperator: lhs = lhs / rhs; break; case TokenType.MultiplyOperator: lhs = lhs * rhs; break; case TokenType.EqualOperator: lhs = ExpressionToken.AreTokensEqual(lhs, rhs); break; case TokenType.LessOperator: lhs = lhs < rhs; break; case TokenType.GreaterOperator: lhs = lhs > rhs; break; case TokenType.LessOrEqualOperator: lhs = lhs <= rhs; break; case TokenType.GreaterOrEqualOperator: lhs = lhs >= rhs; break; case TokenType.AndOperator: lhs = lhs & rhs; break; case TokenType.OrOperator: lhs = lhs | rhs; break; } } return(lhs); }