// precedence-climbing method // https://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing_method private Node parseExpression(Node lhs, int minPrecedence) { spyScannerToken(); // the spied token is an operator and has precedence >= the minimumum precedence while (isOperator(spiedScannerToken.GetValueOrDefault()) && OPERATOR_PRECEDENCE[spiedScannerToken.GetValueOrDefault()].precedence >= minPrecedence) { GingerToken op = spiedScannerToken.GetValueOrDefault(); // move to spied position nextScannerToken(); nextScannerToken(); Node rhs = parseTerminalExpression(); spyScannerToken(); // the spied token is an operator, and its precedence is greater than the previous op's precedence OR it is a right associated operator with precedence equal to op's precedence while (isOperator(spiedScannerToken.GetValueOrDefault()) && (OPERATOR_PRECEDENCE[spiedScannerToken.GetValueOrDefault()].precedence > OPERATOR_PRECEDENCE[op].precedence || (OPERATOR_PRECEDENCE[spiedScannerToken.GetValueOrDefault()].rightAssociated && OPERATOR_PRECEDENCE[spiedScannerToken.GetValueOrDefault()].precedence == OPERATOR_PRECEDENCE[op].precedence))) { rhs = parseExpression(rhs, OPERATOR_PRECEDENCE[spiedScannerToken.GetValueOrDefault()].precedence); spyScannerToken(); } if (Grammar.isBinaryOperator(op)) { lhs = new BinaryOperation(op, lhs, rhs); } else if (Grammar.isConditionOperator(op)) { lhs = new InequalityOperation(op, lhs, rhs); } else { throw new ParseException(scanner.row, scanner.col, $"Expected '{GingerToken.Addition.ToString()}', or '{GingerToken.LessThan.ToString()}', found '{currentScannerToken.ToString()}'", ExceptionLevel.ERROR); } } return lhs; }
public void visitInequalityOperation(InequalityOperation c) { return; }
public Inequality(int amount, InequalityOperation operation) { Amount = amount; Operation = operation; }