// operators are now just strings to make things simpler // "(" is the parens operator sclass ShuntingYardCore { new LS operatorStack; new LS outputQueue; swappable void addToOutputQueue(S opOrLiteral) { outputQueue.add(opOrLiteral); } swappable bool isOperator(S token) { false; } // only called on operators swappable int precedence(S op) { ret 1; } swappable bool isLeftAssociative(S op) { true; } static final S OP_PAREN = "("; void handleEOT() { while (nempty(operatorStack)) { var o = popLast(operatorStack); assertNequals(o, OP_PAREN); addToOutputQueue(o); } } void handleToken(S t) { S t = tok.get(iTok); bool op = isOperator(t); if (eq(t, "(")) { finishLiteral(); operatorStack.add(OP_PAREN); } else if (eq(t, ")")) { while (!eq(last(operatorStack), OP_PAREN)) { assertNempty(operatorStack); outputQueue.add(popLast(operatorStack)); } popLast(operatorStack); } else if (op) { S o1 = t, o2; while (!eqOneOf(o2 = last(operatorStack), OP_PAREN, null) && (precedence(o2) > precedence(o1) || precedence(o2) == precedence(o1) && isLeftAssociative(o1))) { ifdef ShuntingYardParser_debug print("popLast"); endifdef outputQueue.add(popLast(operatorStack)); } operatorStack.add(o1); } } }