### Question:
PrecedenceClimbingParser { public SpecialOp special(Object o, int leftPrec, int rightPrec, Special special) { return new SpecialOp(o, leftPrec * 2, rightPrec * 2, special); } private  PrecedenceClimbingParser(List<Token> tokens); Token atom(Object o); Call call(Op op, ImmutableList<Token> args); Op infix(Object o, int precedence, boolean left); Op prefix(Object o, int precedence); Op postfix(Object o, int precedence); SpecialOp special(Object o, int leftPrec, int rightPrec,
      Special special); Token parse(); void partialParse(); @Override String toString(); List<Token> all(); String print(Token token); PrecedenceClimbingParser copy(int start, Predicate<Token> predicate);  }### Answer:
@Test public void testSpecial() { final PrecedenceClimbingParser p = new PrecedenceClimbingParser.Builder() .atom("price") .infix(">", 4, true) .atom("5") .infix("and", 2, true) .atom("price") .special("between", 3, 3, (parser, op) -> new PrecedenceClimbingParser.Result(op.previous, op.next.next.next, parser.call(op, ImmutableList.of(op.previous, op.next, op.next.next.next)))) .atom("1") .infix("+", 5, true) .atom("2") .infix("and", 2, true) .atom("3") .infix("*", 6, true) .atom("4") .infix("and", 2, true) .atom("price") .postfix("is null", 4) .build(); final PrecedenceClimbingParser.Token token = p.parse(); assertThat(p.print(token), is("(((price > 5) and between(price, (1 + 2), (3 * 4)))" + " and (price is null))")); }
@Test void testSpecial() { final PrecedenceClimbingParser p = new PrecedenceClimbingParser.Builder() .atom("price") .infix(">", 4, true) .atom("5") .infix("and", 2, true) .atom("price") .special("between", 3, 3, (parser, op) -> new PrecedenceClimbingParser.Result(op.previous, op.next.next.next, parser.call(op, ImmutableList.of(op.previous, op.next, op.next.next.next)))) .atom("1") .infix("+", 5, true) .atom("2") .infix("and", 2, true) .atom("3") .infix("*", 6, true) .atom("4") .infix("and", 2, true) .atom("price") .postfix("is null", 4) .build(); final PrecedenceClimbingParser.Token token = p.parse(); assertThat(p.print(token), is("(((price > 5) and between(price, (1 + 2), (3 * 4)))" + " and (price is null))")); }