private ExpressionNode ParseSubexpression(int precBound, ExpressionNode left) { while (true) { int curPrec = precedence[(int)curtok.ID]; if (curPrec < precBound) break; int associativity = ASSOC_LEFT; TokenID curOp = curtok.ID; switch (curOp) { case TokenID.Equal: case TokenID.PlusEqual: case TokenID.MinusEqual: case TokenID.StarEqual: case TokenID.SlashEqual: case TokenID.PercentEqual: case TokenID.BAndEqual: case TokenID.BOrEqual: case TokenID.BXorEqual: case TokenID.ShiftLeftEqual: case TokenID.QuestionQuestion: associativity = ASSOC_RIGHT; goto case TokenID.Percent; // "FALL THROUGH" case TokenID.Greater: Advance(); if (curtok.ID == TokenID.Greater && curtok.LastCharWasGreater) { curOp = TokenID.ShiftRight; Advance(); } else if (curtok.ID == TokenID.GreaterEqual && curtok.LastCharWasGreater) { curOp = TokenID.ShiftRightEqual; associativity = ASSOC_RIGHT; Advance(); } goto parseBinOp; case TokenID.Or: case TokenID.And: case TokenID.BOr: case TokenID.BXor: case TokenID.BAnd: case TokenID.EqualEqual: case TokenID.NotEqual: case TokenID.Less: case TokenID.LessEqual: case TokenID.GreaterEqual: case TokenID.ShiftLeft: case TokenID.Plus: case TokenID.Minus: case TokenID.Star: case TokenID.Slash: case TokenID.Percent: Advance(); parseBinOp: 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.Is: case TokenID.As: Advance(); left = new BinaryExpression(curOp, left, ParseType(true)); break; case TokenID.Question: { Advance(); ExpressionNode thenExpr = ParseExpression(); AssertAndAdvance(TokenID.Colon); left = new ConditionalExpression(left, thenExpr, 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: // member access case TokenID.MinusGreater: left = ParseMemberAccess(left); break; default: ReportError("Unexpected token", curtok); return left; } } return left; }
public virtual object VisitInvocationExpression(InvocationExpression invocationExpression, object data) { stackMap.Push(invocationExpression); invocationExpression.LeftSide.AcceptVisitor(this, data); invocationExpression.ArgumentList.AcceptVisitor(this, data); stackMap.Pop(); return null; }