private ExpressionNode parseBinaryExpression(int precedence, ExpressionNode leftExpression) { for (;;) { var prec = 0; var doParseType = false; var op = BinaryOperator.Add; var restorePoint = this.createRestorePoint(); switch (lexicalUnit) { case Multiply: prec = 1; op = BinaryOperator.Multiply; break; case Divide: prec = 1; op = BinaryOperator.Divide; break; case Percent: prec = 1; op = BinaryOperator.Modulo; break; case Plus: prec = 2; op = BinaryOperator.Add; break; case Minus: prec = 2; op = BinaryOperator.Subtract; break; case LeftShift: prec = 3; op = BinaryOperator.LeftShift; break; case GreaterThan: switch (scanner.nextLexicalUnit()) { case GreaterThan: restorePoint = createRestorePoint(); switch (scanner.nextLexicalUnit()) { case GreaterThan: prec = 3; op = BinaryOperator.UnsignedRightShift; break; default: this.restore(restorePoint); prec = 3; op = BinaryOperator.RightShift; break; case GreaterThanOrEqual: this.restore(restorePoint); return leftExpression; } break; default: this.restore(restorePoint); prec = 4; op = BinaryOperator.GreaterThan; break; case GreaterThanOrEqual: this.restore(restorePoint); return leftExpression; } break; case LessThan: prec = 4; op = BinaryOperator.LessThan; break; case LessThanOrEqual: prec = 4; op = BinaryOperator.LessThanOrEqual; break; case GreaterThanOrEqual: prec = 4; op = BinaryOperator.GreaterThanOrEqual; break; case Keyword: switch (scanner.Keyword) { case As: prec = 4; doParseType = true; op = BinaryOperator.As; break; case Instanceof: prec = 4; doParseType = true; op = BinaryOperator.Instanceof; break; default: return leftExpression; } break; case Equal: prec = 5; op = BinaryOperator.Equal; break; case NotEqual: prec = 5; op = BinaryOperator.NotEqual; break; case LogicalAnd: prec = 6; op = BinaryOperator.LogicalAnd; break; case Xor: prec = 7; op = BinaryOperator.Xor; break; case LogicalOr: prec = 8; op = BinaryOperator.LogicalOr; break; case And: prec = 9; op = BinaryOperator.And; break; case Or: prec = 10; op = BinaryOperator.Or; break; case NullCoalescing: prec = 11; op = BinaryOperator.NullCoalescing; break; default: return leftExpression; } if (prec > precedence) { if (op == BinaryOperator.RightShift) { this.restore(restorePoint); } return leftExpression; } nextLexicalUnit(true); var binary = new BinaryExpressionNode { Operator = op, LeftOperand = leftExpression }; copyScannerState(leftExpression, binary); if (doParseType) { var type = new TypeExpressionNode { TypeReference = parseType(true) }; copyScannerState(type.TypeReference, type); type.EndPosition = type.TypeReference.EndPosition; binary.RightOperand = type; } else { binary.RightOperand = parseBinaryExpression(prec - 1, parseUnaryExpression()); } binary.EndPosition = binary.RightOperand.EndPosition; leftExpression = binary; } }