private ExpressionNode ParseSubexpression(int precBound, ExpressionNode left) { while (true) { int curPrec = _precedence[(int)_curtok.TokenId]; if (curPrec < precBound) { break; } int associativity = ASSOC_LEFT; TokenId curOp = _curtok.TokenId; switch (curOp) { case TokenId.Equal: case TokenId.PlusEqual: case TokenId.MinusEqual: case TokenId.StarEqual: case TokenId.SlashEqual: case TokenId.PercentEqual: case TokenId.QuestionQuestion: { associativity = ASSOC_RIGHT; goto case TokenId.Percent; // "FALL THROUGH" } case TokenId.Greater: case TokenId.Or: case TokenId.And: case TokenId.EqualEqual: case TokenId.NotEqual: case TokenId.Less: case TokenId.LessEqual: case TokenId.GreaterEqual: case TokenId.Plus: case TokenId.Minus: case TokenId.Star: case TokenId.Slash: case TokenId.Percent: { Advance(); left = new BinaryExpression(curOp, left, ParseSubexpression(curPrec + associativity)); break; } case TokenId.PlusPlus: // postfix { Advance(); left = new PostIncrementExpression(left); break; } case TokenId.MinusMinus: // postfix { Advance(); left = new PostDecrementExpression(left); break; } case TokenId.Question: { Advance(); ExpressionNode node = ParseExpression(); AssertAndAdvance(TokenId.Colon); left = new ConditionalExpression(left, node, ParseExpression()); break; } case TokenId.LParen: // invocation Advance(); left = new InvocationExpression(left, ParseArgumentList()); AssertAndAdvance(TokenId.RParen); break; case TokenId.LBracket: // element access Advance(); left = new ElementAccessExpression(left, ParseExpressionList()); AssertAndAdvance(TokenId.RBracket); break; case TokenId.Dot: left = ParseMemberAccess(left); break; default: throw new ParseException("Unexpected token"); } } return(left); }
private ExpressionNode ParseSubexpression(int precBound, ExpressionNode left) { while (true) { int curPrec = _precedence[(int)_curtok.TokenId]; if (curPrec < precBound) break; int associativity = ASSOC_LEFT; TokenId curOp = _curtok.TokenId; switch (curOp) { case TokenId.Equal: case TokenId.PlusEqual: case TokenId.MinusEqual: case TokenId.StarEqual: case TokenId.SlashEqual: case TokenId.PercentEqual: case TokenId.QuestionQuestion: { associativity = ASSOC_RIGHT; goto case TokenId.Percent; // "FALL THROUGH" } case TokenId.Greater: case TokenId.Or: case TokenId.And: case TokenId.EqualEqual: case TokenId.NotEqual: case TokenId.Less: case TokenId.LessEqual: case TokenId.GreaterEqual: case TokenId.Plus: case TokenId.Minus: case TokenId.Star: case TokenId.Slash: case TokenId.Percent: { Advance(); left = new BinaryExpression(curOp, left, ParseSubexpression(curPrec + associativity)); break; } case TokenId.PlusPlus: // postfix { Advance(); left = new PostIncrementExpression(left); break; } case TokenId.MinusMinus: // postfix { Advance(); left = new PostDecrementExpression(left); break; } case TokenId.Question: { Advance(); ExpressionNode node = ParseExpression(); AssertAndAdvance(TokenId.Colon); left = new ConditionalExpression(left, node, ParseExpression()); break; } case TokenId.LParen: // invocation Advance(); left = new InvocationExpression(left, ParseArgumentList()); AssertAndAdvance(TokenId.RParen); break; case TokenId.LBracket: // element access Advance(); left = new ElementAccessExpression(left, ParseExpressionList()); AssertAndAdvance(TokenId.RBracket); break; case TokenId.Dot: left = ParseMemberAccess(left); break; default: throw new ParseException("Unexpected token"); } } return left; }