void setInput(CharBuffer cb, boolean skipWhitespace) { this.tokenizer = new Tokenizer(cb, skipWhitespace); operators().clear(); operands().clear(); }
private void parseArguments() { assert state.next() == Token.OPEN; state.consume(); state.operators().push(Operator.SENTINEL); int na = 0; Token t; while ((t = state.next()) != Token.CLOSE) { if (na > 0) { if (t == Token.COMMA) state.consume(); else state.error(Token.COMMA, t); } parseExpression(); ++na; } state.expect(Token.CLOSE); state.operators.pop(); List<Object> args = new java.util.ArrayList<Object>(); while (na > 0) { args.add(state.operands.pop()); --na; } state.operands.push(new Expression(Operator.GROUP, args)); }
private void parsePrimary() { Token t0 = state.next(); if (t0 == null) { state.error(); } else if (t0.isLiteral()) { state.consume(); Token t1 = state.next(); if (t1 == Token.OPEN) { state.pushOperator(Operator.APPLY); state.pushOperand(t0); parseArguments(); } else state.pushOperand(t0); } else if (t0 == Token.OPEN) { state.consume(); state.operators().push(Operator.SENTINEL); parseExpression(); state.expect(Token.CLOSE); state.operators.pop(); } else if (t0.isUnaryOp()) { state.consume(); state.pushOperator(Operator.fromToken(t0, OperatorContext.UNARY)); parsePrimary(); } else state.error(t0); }
Operator popOperator() { assert !operators().empty(); Operator top = topOperator(); if (top != null) { if (top.isBinary() || (top == Operator.APPLY)) { assert operands().size() > 1; Object o1 = operands().pop(); Object o0 = operands().pop(); pushOperand(new Expression(operators().pop(), Arrays.asList(new Object[]{ o0, o1 }))); return top; } else if (top.isUnary()) { assert operands().size() > 0; Object o0 = operands().pop(); pushOperand(new Expression(operators().pop(), o0)); return top; } else { assert false; throw new ParserStateException("unexpected operator: " + top); } } else throw new ParserStateException("operator stack is empty"); }
Condition parse(CharBuffer cb) { if (cb.hasRemaining()) { state.setInput(cb, skipWhitespace); state.operators().push(Operator.SENTINEL); parseExpression(); state.expect(Token.EOS); return new Condition(state.topOperand()); } else throw new ParserException("empty condition"); }
void pushOperator(Operator op) { Operator top; while ((top = topOperator()) != null) { if (top.comparePrecedence(op) > 0) popOperator(); else break; } operators().push(op); }