private static IArithExpression ParseExpression(Token start, Func <Token, bool> endOfExpression, TokenCursor tokens, bool moveToPrevAtEnd) { var current = start; IArithExpression resultExpr = null; //while next && end(next).not() while (current.IsNotNull()) { resultExpr = ParseToken(current, resultExpr, tokens); current = tokens.Next(); if (current.IsNotNull() && endOfExpression(current)) { if (moveToPrevAtEnd) { tokens.MovePrev(); } break; } } return(resultExpr); //operators precedence: //- test for multiplicative operator - build one first //- test for expression group - (....) //- test for function call - ID(args) //prevExpression is not applicable in case of ROperand parsing }
public IArithExpression Parse(string text) { var lexer = new Lexer(text); using (var tokens = new TokenCursor(lexer.Tokens())) { Func <Token, bool> toEnd = t => false; var expression = ParseExpression(tokens.Next(), toEnd, tokens, false); if (expression.IsNull()) { throw new ParsingException("Empty expression"); } return(expression); } }
private static IArithExpression ParseToken(Token token, IArithExpression prevExpr, TokenCursor tokens) { switch (token.Type) { case TokenType.Value: return(ParseValue(token)); case TokenType.AdditiveOperator: case TokenType.MultiplicativeOperator: return(ParseOperator(token, prevExpr, tokens)); case TokenType.OParenthesis: return(ParseGroup(tokens.Next(), tokens)); case TokenType.CParenthesis: return(prevExpr); default: throw new ParsingException("Unexpected token: " + token); } }
private static IArithExpression ParseOperator(Token operatorToken, IArithExpression lOperand, TokenCursor tokens) { var rOperand = ParseRightOperand(tokens.Next(), operatorToken, tokens); return(OperatorExpression.Create(operatorToken.Value, lOperand, rOperand)); }