DeclarationParser { public static Parser<Program> program() { Parser.Reference<Member> memberRef = Parser.newReference(); Parser.Reference<Statement> stmtRef = Parser.newReference(); Parser<Expression> expr = ExpressionParser.expression(body(memberRef.lazy()), stmtRef.lazy()); Parser<Statement> stmt = StatementParser.statement(expr); stmtRef.set(stmt); Parser<Modifier> mod = StatementParser.modifier(expr); Parser.Reference<Declaration> decRef = Parser.newReference(); Parser<Member> member = Parsers.or( fieldDef(expr), methodDef(mod, expr, stmt), constructorDef(mod, stmt), initializerDef(stmt), nestedDef(decRef.lazy())); memberRef.set(member); Parser<Declaration> declaration = Parsers.or( classDef(mod, member), interfaceDef(mod, member), enumDef(expr, member), annotationDef(mod, member)); decRef.set(declaration); return Parsers.sequence(PACKAGE.optional(), IMPORT.many(), declaration.many(), Program::new); }  static Parser<Program> program(); static Program parse(String source); static Program parse(URL url);  }
@Test public void testProgram() { Parser<Program> parser = DeclarationParser.program(); TerminalParserTest.assertResult(parser, "package foo; import foo.bar.*; class Foo {int[] a = {1}; Foo(){}}", Program.class, "package foo; import foo.bar.*; class Foo {int[] a = {1}; Foo() {}}"); TerminalParserTest.assertResult(parser, "class Foo {{} static {}}", Program.class, "class Foo {{} static {}}"); TerminalParserTest.assertResult(parser, "package foo; import foo.bar.*; enum Foo {}", Program.class, "package foo; import foo.bar.*; enum Foo {}"); TerminalParserTest.assertResult(parser, "enum Foo {;static {1;} static {2;} {3;} {4;}}", Program.class, "enum Foo {; static {1;} static {2;} {3;} {4;}}"); TerminalParserTest.assertResult(parser, "package foo; import foo.bar.*; interface Foo {int i = 1;}", Program.class, "package foo; import foo.bar.*; interface Foo {int i = 1;}"); TerminalParserTest.assertResult(parser, "package foo; import foo.bar.*; @interface Foo {int[] value() default {1};}", Program.class, "package foo; import foo.bar.*; @interface Foo {int[] value() default {1};}"); TerminalParserTest.assertResult(parser, "import foo.bar.*; class Foo<T> implements Bar {} interface Bar {}", Program.class, "import foo.bar.*; class Foo<T> implements Bar {} interface Bar {}"); TerminalParserTest.assertResult(parser, "class Foo {class Bar {}}", Program.class, "class Foo {class Bar {}}"); TerminalParserTest.assertResult(parser, "class Foo {private static final class Bar {}}", Program.class, "class Foo {private static final class Bar {}}"); TerminalParserTest.assertResult(parser, "class Foo {enum Bar {B}}", Program.class, "class Foo {enum Bar {B}}"); TerminalParserTest.assertResult(parser, "class Foo {@interface Bar {;;}}", Program.class, "class Foo {@interface Bar {}}"); }