ExpressionParser { static Parser<Expression> expression( Parser<Expression> atom, Parser<DefBody> classBody, Parser<Statement> statement) { Parser.Reference<Expression> ref = Parser.newReference(); Parser<Expression> lazy = ref.lazy(); atom = Parsers.or(castOrExpression(lazy), simpleNewExpression(lazy, classBody), newArrayWithExplicitLength(lazy), newArrayWithoutExplicitLength(lazy), simpleMethodCall(lazy), lambdaExpression(lazy, statement), atom); Parser<Expression> parser = new OperatorTable<Expression>() .postfix(subscript(lazy), 200) .postfix(qualifiedMethodCall(lazy), 200) .postfix(qualifiedNew(lazy, classBody), 200) .postfix(METHOD_REFERENCE, 200) .postfix(CONSTRUCTOR_REFERENCE, 20) .postfix(QUALIFIED_EXPR, 200) .postfix(postfix(Operator.POST_INC), 200) .postfix(postfix(Operator.POST_DEC), 200) .prefix(prefix(Operator.INC), 190) .prefix(prefix(Operator.DEC), 190) .prefix(prefix(Operator.POSITIVE), 190) .prefix(prefix(Operator.NEGATIVE), 190) .prefix(prefix(Operator.INC), 190) .prefix(prefix(Operator.DEC), 190) .prefix(prefix(Operator.NOT), 190) .prefix(prefix(Operator.BITWISE_NOT), 190) .infixl(binary(Operator.MUL), 100) .infixl(binary(Operator.DIV), 100) .infixl(binary(Operator.MOD), 100) .infixl(binary(Operator.DIV), 100) .infixl(binary(Operator.PLUS), 90) .infixl(binary(Operator.MINUS), 90) .infixl(binary(Operator.LSHIFT), 80) .infixl(binary(Operator.RSHIFT), 80) .infixl(binary(Operator.UNSIGNED_RSHIFT), 80) .infixl(binary(Operator.LE), 70) .infixl(binary(Operator.GE), 70) .infixl(binary(Operator.LT), 70) .infixl(binary(Operator.GT), 70) .postfix(INSTANCE_OF, 65) .infixl(binary(Operator.EQ), 60) .infixl(binary(Operator.NE), 60) .infixl(binary(Operator.BITWISE_AND), 50) .infixl(binary(Operator.BITWISE_XOR), 40) .infixl(binary(Operator.BITWISE_OR), 30) .infixl(binary(Operator.AND), 20) .infixl(binary(Operator.OR), 10) .infixr(conditional(lazy), 5) .infixr(binary(Operator.ASSIGNMENT), 0) .infixr(binary(Operator.APLUS), 0) .infixr(binary(Operator.AMINUS), 0) .infixr(binary(Operator.AMUL), 0) .infixr(binary(Operator.ADIV), 0) .infixr(binary(Operator.AMOD), 0) .infixr(binary(Operator.AAND), 0) .infixr(binary(Operator.AOR), 0) .infixr(binary(Operator.AXOR), 0) .infixr(binary(Operator.ALSHIFT), 0) .infixr(binary(Operator.ARSHIFT), 0) .infixr(binary(Operator.UNSIGNED_ARSHIFT), 0) .build(atom); ref.set(parser); return parser; }  static Parser<Expression> expression(
      Parser<DefBody> classBody, Parser<Statement> statement); static Parser<Expression> arrayInitializer(Parser<Expression> expr);  }
@Test public void testExpression() { Parser<Expression> parser = ExpressionParser.expression(ExpressionParser.IDENTIFIER, EMPTY_BODY, StatementParser.expression(ExpressionParser.IDENTIFIER)); TerminalParserTest.assertResult(parser, "foo", Identifier.class, "foo"); TerminalParserTest.assertResult(parser, "(foo)", Identifier.class, "foo"); TerminalParserTest.assertResult(parser, "((foo))", Identifier.class, "foo"); TerminalParserTest.assertResult(parser, "foo[bar[baz]]", ArraySubscriptExpression.class, "foo[bar[baz]]"); TerminalParserTest.assertResult(parser, "(foo) (bar)", CastExpression.class, "((foo) bar)"); TerminalParserTest.assertResult(parser, "(foo) (bar) baz", CastExpression.class, "((foo) ((bar) baz))"); TerminalParserTest.assertResult(parser, "new Foo(a,b)", NewExpression.class, "new Foo(a, b)"); TerminalParserTest.assertResult(parser, "new int[n]", NewArrayExpression.class, "new int[n]"); TerminalParserTest.assertResult(parser, "new int[n]{}", NewArrayExpression.class, "new int[n] {}"); TerminalParserTest.assertResult(parser, "new int[]{a,b,c}", NewArrayExpression.class, "new int[] {a, b, c}"); TerminalParserTest.assertResult(parser, "foo(a)", MethodCallExpression.class, "foo(a)"); TerminalParserTest.assertResult(parser, "foo.f()", MethodCallExpression.class, "foo.f()"); TerminalParserTest.assertResult(parser, "foo().bar().baz()", MethodCallExpression.class, "foo().bar().baz()"); TerminalParserTest.assertResult(parser, "foo.new Foo()", NewExpression.class, "foo.new Foo()"); TerminalParserTest.assertResult(parser, "foo.bar.baz", QualifiedExpression.class, "((foo.bar).baz)"); TerminalParserTest.assertResult(parser, "foo.bar.new Foo()", NewExpression.class, "(foo.bar).new Foo()"); TerminalParserTest.assertResult(parser, "foo++", PostfixUnaryExpression.class, "(foo++)"); TerminalParserTest.assertResult(parser, "foo++--", PostfixUnaryExpression.class, "((foo++)--)"); TerminalParserTest.assertResult(parser, "++foo", PrefixUnaryExpression.class, "(++foo)"); TerminalParserTest.assertResult(parser, "++--foo", PrefixUnaryExpression.class, "(++(--foo))"); TerminalParserTest.assertResult(parser, "++foo--", PrefixUnaryExpression.class, "(++(foo--))"); TerminalParserTest.assertResult(parser, "+foo", PrefixUnaryExpression.class, "(+foo)"); TerminalParserTest.assertResult(parser, "+-foo", PrefixUnaryExpression.class, "(+(-foo))"); TerminalParserTest.assertResult(parser, "!foo", PrefixUnaryExpression.class, "(!foo)"); TerminalParserTest.assertResult(parser, "!!foo", PrefixUnaryExpression.class, "(!(!foo))"); TerminalParserTest.assertResult(parser, "~foo", PrefixUnaryExpression.class, "(~foo)"); TerminalParserTest.assertResult(parser, "~~foo", PrefixUnaryExpression.class, "(~(~foo))"); TerminalParserTest.assertResult(parser, "foo+bar", BinaryExpression.class, "(foo + bar)"); TerminalParserTest.assertResult(parser, "a+b*c/d-e%f", BinaryExpression.class, "((a + ((b * c) / d)) - (e % f))"); TerminalParserTest.assertResult(parser, "a<<b", BinaryExpression.class, "(a << b)"); TerminalParserTest.assertResult(parser, "a>>b", BinaryExpression.class, "(a >> b)"); TerminalParserTest.assertResult(parser, "a>>>b", BinaryExpression.class, "(a >>> b)"); TerminalParserTest.assertResult(parser, "a>b", BinaryExpression.class, "(a > b)"); TerminalParserTest.assertResult(parser, "a>b<c", BinaryExpression.class, "((a > b) < c)"); TerminalParserTest.assertResult(parser, "a>=b", BinaryExpression.class, "(a >= b)"); TerminalParserTest.assertResult(parser, "a>=b<=c", BinaryExpression.class, "((a >= b) <= c)"); TerminalParserTest.assertResult(parser, "a instanceof int", InstanceOfExpression.class, "(a instanceof int)"); TerminalParserTest.assertResult(parser, "a instanceof int instanceof boolean", InstanceOfExpression.class, "((a instanceof int) instanceof boolean)"); TerminalParserTest.assertResult(parser, "a==b", BinaryExpression.class, "(a == b)"); TerminalParserTest.assertResult(parser, "a==b!=c", BinaryExpression.class, "((a == b) != c)"); TerminalParserTest.assertResult(parser, "a&b&c", BinaryExpression.class, "((a & b) & c)"); TerminalParserTest.assertResult(parser, "a|b&c", BinaryExpression.class, "(a | (b & c))"); TerminalParserTest.assertResult(parser, "a&&b|c", BinaryExpression.class, "(a && (b | c))"); TerminalParserTest.assertResult(parser, "!a||b&&c", BinaryExpression.class, "((!a) || (b && c))"); TerminalParserTest.assertResult(parser, "x?c:d", ConditionalExpression.class, "(x ? c : d)"); TerminalParserTest.assertResult(parser, "a==b?b==c?x:y:z+n ? m: n", ConditionalExpression.class, "((a == b) ? ((b == c) ? x : y) : ((z + n) ? m : n))"); TerminalParserTest.assertResult(parser, "a=b=c", BinaryExpression.class, "(a = (b = c))"); TerminalParserTest.assertResult(parser, "a+=b+=c", BinaryExpression.class, "(a += (b += c))"); TerminalParserTest.assertResult(parser, "a-=b-=c", BinaryExpression.class, "(a -= (b -= c))"); TerminalParserTest.assertResult(parser, "a*=b*=c", BinaryExpression.class, "(a *= (b *= c))"); TerminalParserTest.assertResult(parser, "a/=b/=c", BinaryExpression.class, "(a /= (b /= c))"); TerminalParserTest.assertResult(parser, "a%=b%=c", BinaryExpression.class, "(a %= (b %= c))"); TerminalParserTest.assertResult(parser, "a&=b&=c", BinaryExpression.class, "(a &= (b &= c))"); TerminalParserTest.assertResult(parser, "a|=b|=c", BinaryExpression.class, "(a |= (b |= c))"); TerminalParserTest.assertResult(parser, "a>>=b>>=c", BinaryExpression.class, "(a >>= (b >>= c))"); TerminalParserTest.assertResult(parser, "a>>>=b>>>=c", BinaryExpression.class, "(a >>>= (b >>>= c))"); TerminalParserTest.assertResult(parser, "a<<=b<<=c", BinaryExpression.class, "(a <<= (b <<= c))"); TerminalParserTest.assertResult(parser, "a^=b^=c", BinaryExpression.class, "(a ^= (b ^= c))"); TerminalParserTest.assertResult(parser, "Foo::new", ConstructorReference.class, "Foo::new"); TerminalParserTest.assertResult(parser, "Foo.Bar::new", ConstructorReference.class, "(Foo.Bar)::new"); TerminalParserTest.assertResult(parser, "x::new", ConstructorReference.class, "x::new"); TerminalParserTest.assertResult(parser, "Foo::create", MethodReference.class, "Foo::create"); TerminalParserTest.assertResult(parser, "Foo.Bar::create", MethodReference.class, "(Foo.Bar)::create"); TerminalParserTest.assertResult(parser, "x::create", MethodReference.class, "x::create"); TerminalParserTest.assertResult(parser, "Foo::<T>create", MethodReference.class, "Foo::<T>create"); TerminalParserTest.assertResult(parser, "Foo.Bar::<T>create", MethodReference.class, "(Foo.Bar)::<T>create"); TerminalParserTest.assertResult(parser, "x::<String>create", MethodReference.class, "x::<String>create"); TerminalParserTest.assertResult(parser, "() -> a", LambdaExpression.class, "() -> a;"); TerminalParserTest.assertResult(parser, "() -> {a;}", LambdaExpression.class, "() -> {a;}"); TerminalParserTest.assertResult(parser, "x -> {}", LambdaExpression.class, "(x) -> {}"); TerminalParserTest.assertResult(parser, "(x, y) -> {}", LambdaExpression.class, "(x, y) -> {}"); TerminalParserTest.assertResult(parser, "(String x, int y) -> {}", LambdaExpression.class, "(String x, int y) -> {}"); TerminalParserTest.assertResult(parser, "(String x, int y) -> {xyz;}", LambdaExpression.class, "(String x, int y) -> {xyz;}"); }