private static Expression ParseTernary(ExpressionLexer lexer) { var expr = ParseCondCombo(lexer); if (lexer.PeekNextToken() == ExprTokenType.QuestionMark) { lexer.GetNextToken(ExprTokenType.QuestionMark); var trueValue = ParseTernary(lexer); lexer.GetNextToken(ExprTokenType.Colon); var falseValue = ParseTernary(lexer); return(new TernaryExpression(expr, trueValue, falseValue)); } return(expr); }
public static Expression Parse(string source) { var lexer = new ExpressionLexer(source); Expression result = ParseTernary(lexer); lexer.GetNextToken(ExprTokenType.EOF); result.Source = source; return(result); }
private static Expression ParseFactor(ExpressionLexer lexer) { ExprTokenType tokenType = lexer.PeekNextToken(); if (tokenType == ExprTokenType.Number) { return(new PrimitiveExpression((int)lexer.GetNextToken(ExprTokenType.Number))); } if (tokenType == ExprTokenType.String) { return(new PrimitiveExpression((string)lexer.GetNextToken(ExprTokenType.String))); } if (tokenType == ExprTokenType.Symbol) { string symbol = (string)lexer.GetNextToken(ExprTokenType.Symbol); if (lexer.PeekNextToken() == ExprTokenType.Dot) { lexer.GetNextToken(ExprTokenType.Dot); Expression exprInContext = ParseFactor(lexer); return(new ContextExpression(symbol, exprInContext, new Expression[0])); } if (lexer.PeekNextToken() == ExprTokenType.Open) { lexer.GetNextToken(ExprTokenType.Open); var parameters = new List <Expression>(); while (lexer.PeekNextToken() != ExprTokenType.Close) { if (parameters.Count > 0) { lexer.GetNextToken(ExprTokenType.Comma); } parameters.Add(ParseCondCombo(lexer)); } lexer.GetNextToken(ExprTokenType.Close); if (lexer.PeekNextToken() == ExprTokenType.Dot) { lexer.GetNextToken(ExprTokenType.Dot); Expression exprInContext = ParseFactor(lexer); return(new ContextExpression(symbol, exprInContext, parameters.ToArray())); } return(new FunctionExpression(symbol, parameters.ToArray())); } return(new SymbolExpression(symbol)); } if (tokenType == ExprTokenType.Open) { lexer.GetNextToken(ExprTokenType.Open); Expression result = ParseCondCombo(lexer); lexer.GetNextToken(ExprTokenType.Close); return(result); } if (tokenType == ExprTokenType.Minus || tokenType == ExprTokenType.NOT) { lexer.GetNextToken(tokenType); return(new UnaryExpression(ParseFactor(lexer), tokenType)); } throw new ParseException("Unexpected token " + tokenType, lexer.CurrentPosition); }