Class OperatorTable<T>

java.lang.Object
com.google.common.labs.parse.OperatorTable<T>

public final class OperatorTable<T> extends Object
Provides a fluent API for building an operator precedence grammar.

For example, to build a simple calculator parser, you can implement it as:


 Parser<Integer> calculator = new OperatorTable<Integer>()
     .leftAssociative("+", (l, r) -> l + r, 10)
     .leftAssociative("-", (l, r) -> l - r, 10)
     .leftAssociative("*", (l, r) -> l * r), 20)
     .rightAssociative("^", (l, r) -> pow(l, r), 30)
     .prefix("-", n -> -n, 40)
     .postfix("++", n -> n + 1, 40)
     .postfix("--", n -> n - 1, 40)
     .build(consecutive(DIGIT, "number").map(Integer::parseInt));

 calculator.parse("1+2*3^2") // 19
 calculator.parseSkipping(whitespace(), "1 + 2") // 3
 
  • Constructor Details

    • OperatorTable

      public OperatorTable()
  • Method Details

    • prefix

      @CanIgnoreReturnValue public OperatorTable<T> prefix(String op, UnaryOperator<T> operator, int precedence)
      Adds a prefix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • prefix

      @CanIgnoreReturnValue public OperatorTable<T> prefix(Parser<? extends UnaryOperator<T>> operator, int precedence)
      Adds a prefix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • postfix

      @CanIgnoreReturnValue public OperatorTable<T> postfix(String op, UnaryOperator<T> operator, int precedence)
      Adds a postfix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • postfix

      @CanIgnoreReturnValue public <S> OperatorTable<T> postfix(Parser<S> operator, BiFunction<? super T, ? super S, ? extends T> postfixFunction, int precedence)
      Adds a postfix operator with the given precedence to the table. This operator will call postfixFunction.apply(operand, postfixValue), where postfixValue is the result of the postfix operator parser. The higher precedence value the higher precedence it is.

      This method is particularly useful to express otherwise-left-recursive grammars. For example, if you need to parse Java method invocations such as expression.doSomething(foo, bar), the receiver part is an expression and the method invocation is also an expression, resulting in a left recursive grammar. Using OperatorTable.postfix(), you basically think of the .doSomething(foo, bar) part as an abstract postfix operator that turns an expression into another expression:

      
       Parser<Expression> expression = Parser.define(
           rule -> {  // recursive because the parameters are also expressions
             Parser<FunctionInvocation> methodInvocation = Parser.sequence(
                 word(), rule.zeroOrMoreDelimitedBy(",").between("(", ")"),
                 FunctionInvocation::new);
             return new OperatorTable<Expression>()
                 // Assuming you have the following constructor:
                 //   MethodInvocation(Expression receiver, FunctionInvocation invocation);
                 .postfix(string(".").then(methodInvocation), MethodInvocation::new, 10)
                 ... // other operators
                 .build();
           });
       
      Since:
      9.5
    • postfix

      @CanIgnoreReturnValue public OperatorTable<T> postfix(Parser<? extends UnaryOperator<T>> operator, int precedence)
      Adds a postfix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • leftAssociative

      @CanIgnoreReturnValue public OperatorTable<T> leftAssociative(String op, BinaryOperator<T> operator, int precedence)
      Adds a left-associative infix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • leftAssociative

      @CanIgnoreReturnValue public OperatorTable<T> leftAssociative(Parser<? extends BinaryOperator<T>> operator, int precedence)
      Adds a left-associative infix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • nonAssociative

      @CanIgnoreReturnValue public OperatorTable<T> nonAssociative(String op, BinaryOperator<T> operator, int precedence)
      Adds a non-associative infix operator (e.g. a comparison operator like '>'), with the given precedence to the table. The higher precedence value the higher precedence it is.
    • nonAssociative

      @CanIgnoreReturnValue public OperatorTable<T> nonAssociative(Parser<? extends BinaryOperator<T>> operator, int precedence)
      Adds a non-associative infix operator (e.g. a comparison operator like '>'), with the given precedence to the table. The higher precedence value the higher precedence it is.
    • rightAssociative

      @CanIgnoreReturnValue public OperatorTable<T> rightAssociative(String op, BinaryOperator<T> operator, int precedence)
      Adds a right-associative infix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • rightAssociative

      @CanIgnoreReturnValue public OperatorTable<T> rightAssociative(Parser<? extends BinaryOperator<T>> operator, int precedence)
      Adds a right-associative infix operator with the given precedence to the table. The higher precedence value the higher precedence it is.
    • build

      public Parser<T> build(Parser<? extends T> operand)
      Builds a parser with the configured operators applied to the given operand.