import gi.*;

class Java20 extends Grammar {

	Java20() {

		/**
		* Grammar for Java 2.0.
		*
		* Nonterminal - first letter uppercase
		* TERMINAL - all letters uppercase
		* keyword - all letters lowercase
		*/
		int INFINITY = -1;

		/**
		* 19.3 Terminals from section 3.6: White Space: [[:space:]]
		*/
		put("WHITE_SPACE", PosixClass.space());

		/**
		* 19.3 Terminals from section 3.7: Comment
		*/
		put("COMMENT", new Union(

			//
			// Traditional Comment: /\*[^*]+(\*([^*/][^*]*)?)*\*/
			//
			new Concatenation(
				new Singleton("/*"), new Concatenation(
				new Repetition(new NonMatch("*"), 1, INFINITY), new Concatenation(
				new Repetition(
					new Concatenation(
						new Singleton("*"),
						new Repetition(new Concatenation(
							new NonMatch("*/"),
							new Repetition(new NonMatch("*"), 0, INFINITY)
						), 0, 1)
					), 0, INFINITY
				),
				new Singleton("*/")
			))), new Union(

			/**
			* End Of Line Comment: //[^\n]*\n
			*/
			new Concatenation(
				new Singleton("//"), new Concatenation(
				new Repetition(new NonMatch("\n"), 0, INFINITY),
				new Singleton("\n")
			)),

			//
			// Documentation Comment: /\*\*(([^*/][^*]*)?\*)*/
			//
			new Concatenation(
				new Singleton("/**"), new Concatenation(
				new Repetition(
					new Concatenation(
						new Repetition(new Concatenation(
							new NonMatch("*/"),
							new Repetition(new NonMatch("*"), 0, INFINITY)
						), 0, 1),
						new Singleton("*")
					), 0, INFINITY
				),
				new Singleton("/")
			))
		)));

		put("IDENTIFIER", new Concatenation(
			new Union(
				PosixClass.alpha(),
				new Match("_$")
			),
			new Repetition(
				new Union(
					PosixClass.alnum(),
					new Match("_$")
				), 0, INFINITY
			)
		));

		/**
		* 19.3 Terminals from section 3.9: Keyword (recognized but not in the Java grammar)
		*/
		put("KEYWORD", new Union(
			new Singleton("const"),
			new Singleton("goto")
		));

		/**
		* 19.3 Terminals from section 3.10.1: Integer Literal
		*/
		put("INTEGER_LITERAL", new Concatenation(
			new Union(
				/**
				* Decimal Integer Literal: 0|[1-9][[:digit:]]*
				*/
				new Singleton("0"), new Union(

				new Concatenation(
					new Range('1', '9'),
					new Repetition(PosixClass.digit(), 0, INFINITY)
				), new Union(

				/**
				* Hexadecimal Integer Literal: 0[xX][[:xdigit:]]+
				*/
				new Concatenation(
					new Singleton("0"), new Concatenation(
					new Match("xX"),
					new Repetition(PosixClass.xdigit(), 1, INFINITY)
				)),

				/**
				* Octal Integer Literal: 0[0-7]+
				*/
				new Concatenation(
					new Singleton("0"),
					new Repetition(new Range('0', '7'), 1, INFINITY)
				)
			))),
			new Repetition(new Match("lL"), 0, 1)
		));

		/**
		* 19.3 Terminals from section 3.10.2: Floating-Point Literal
		*/
		put("FLOATING_POINT_LITERAL", new Union(

			/**
			* [[:digit:]]+\.[[:digit:]]*([eE][-+]?[[:digit:]]+)?[fFdD]?
			*/
			new Concatenation(
				new Repetition(PosixClass.digit(), 1, INFINITY), new Concatenation(
				new Singleton("."), new Concatenation(
				new Repetition(PosixClass.digit(), 0, INFINITY), new Concatenation(
				new Repetition(new Concatenation(
					new Match("eE"), new Concatenation(
					new Repetition(new Match("-+"), 0, 1),
					new Repetition(PosixClass.digit(), 1, INFINITY)
				)), 0, 1),
				new Repetition(new Match("fFdD"), 0, 1)
			)))), new Union(

			/**
			* \.[[:digit:]]+([eE][-+]?[[:digit:]]+)?[fFdD]?
			*/
			new Concatenation(
				new Singleton("."), new Concatenation(
				new Repetition(PosixClass.digit(), 1, INFINITY), new Concatenation(
				new Repetition(new Concatenation(
					new Match("eE"), new Concatenation(
					new Repetition(new Match("-+"), 0, 1),
					new Repetition(PosixClass.digit(), 1, INFINITY)
				)), 0, 1),
				new Repetition(new Match("fFdD"), 0, 1)
			))), new Union(

			/**
			* [[:digit:]]+[eE][-+]?[[:digit:]]+[fFdD]?
			*/
			new Concatenation(
				new Repetition(PosixClass.digit(), 1, INFINITY), new Concatenation(
				new Match("eE"), new Concatenation(
				new Repetition(new Match("-+"), 0, 1), new Concatenation(
				new Repetition(PosixClass.digit(), 1, INFINITY),
				new Repetition(new Match("fFdD"), 0, 1)
			)))),

			/**
			* [[:digit:]]+([eE][-+]?[[:digit:]]+)?[fFdD]
			*/
			new Concatenation(
				new Repetition(PosixClass.digit(), 1, INFINITY), new Concatenation(
				new Repetition(new Concatenation(
					new Match("eE"), new Concatenation(
					new Repetition(new Match("-+"), 0, 1),
					new Repetition(PosixClass.digit(), 1, INFINITY)
				)), 0, 1),
				new Match("fFdD")
			))
		))));

		/**
		* 19.3 Terminals from section 3.10.3: Boolean Literal
		*/
		put("BOOLEAN_LITERAL", new Union(
			new Singleton("true"),
			new Singleton("false")
		));

		/**
		* 19.3 Terminals from section 3.10.4: Character Literal
		*/
		put("CHARACTER_LITERAL", new Concatenation(
			new Singleton("'"), new Concatenation(
			new Union(

				/**
				* Single Character: [^\r\n'\\]
				*/
				new NonMatch("\r\n'\\"),

				/**
				* Escape Sequence: \\([btnfr\"'\\]|[0-3]?[0-7]{1,2})
				*/
				new Concatenation(
					new Singleton("\\"),
					new Union(
						new Match("btnfr\"'\\"),
						new Concatenation(
							new Repetition(new Range('0', '3'), 0, 1),
							new Repetition(new Range('0', '7'), 1, 2)
						)
					)
				)
			),
			new Singleton("'")
		)));

		/**
		* 19.3 Terminals from section 3.10.5: String Literal
		*/
		put("STRING_LITERAL", new Concatenation(
			new Singleton("\""), new Concatenation(
			new Repetition(
				new Union(

					/**
					* Single Character: [^\r\n"\\]
					*/
					new NonMatch("\r\n\"\\"),

					/**
					* Escape Sequence: \\([btnfr\"'\\]|[0-3]?[0-7]{1,2})
					*/
					new Concatenation(
						new Singleton("\\"),
						new Union(
							new Match("btnfr\"'\\"),
							new Concatenation(
								new Repetition(new Range('0', '3'), 0, 1),
								new Repetition(new Range('0', '7'), 1, 2)
							)
						)
					)
				), 0, INFINITY
			),
			new Singleton("\"")
		)));

		/**
		* 19.3 Terminals section 3.10.7: Null Literal
		*/
		put("NULL_LITERAL", new Singleton("null"));

		/**
		* Syntax Specification
		*/
		put("CompilationUnit", new Object[][] {
			{"ImportDeclarations", "TypeDeclarations"},
			{"package", "QualifiedIdentifier", ";", "ImportDeclarations", "TypeDeclarations"},
		});
		put("QualifiedIdentifier", new Object[][] {
			{"IDENTIFIER"},
			{"QualifiedIdentifier", ".", "IDENTIFIER"},
		});
		put("Literal", new Object[][] {
			{"INTEGER_LITERAL"},
			{"FLOATING_POINT_LITERAL"},
			{"CHARACTER_LITERAL"},
			{"STRING_LITERAL"},
			{"BOOLEAN_LITERAL"},
			{"NULL_LITERAL"},
		});
		put("Expression", new Object[][] {
			{"Expression1"},
			{"Expression1", "AssignmentOperator", "Expression1"},
		});
		put("AssignmentOperator", new Object[][] {
			{"="},
			{"+="},
			{"-="},
			{"*="},
			{"/="},
			{"&="},
			{"|="},
			{"^="},
			{"%="},
			{"<<="},
			{">>="},
			{">>>="},
		});
		put("Type", new Object[][] {
			{"QualifiedIdentifier", "BracketsOpt"},
			{"BasicType"},
		});
		put("StatementExpression", new Object[][] {
			{"Expression"}
		});
		put("ConstantExpression", new Object[][] {
			{"Expression"}
		});
		put("Expression1", new Object[][] {
			{"Expression2", "Expression1Rest"}
		});
		put("Expression1Rest", new Object[][] {
			{},
			{"?", "Expression", ":", "Expression1"},
		});
		put("Expression2", new Object[][] {
			{"Expression3", "Expression2Rest"}
		});
		put("Expression2Rest", new Object[][] {
			{"Infixops"},
			{"instanceof", "Type"},
		});
		put("Infixops", new Object[][] {
			{},
			{"Infixop", "Expression3", "Infixops"},
		});
		put("Infixop", new Object[][] {
			{"||"},
			{"&&"},
			{"|"},
			{"^"},
			{"&"},
			{"=="},
			{"!="},
			{"<"},
			{">"},
			{"<="},
			{">="},
			{"<<"},
			{">>"},
			{">>>"},
			{"+"},
			{"-"},
			{"*"},
			{"/"},
			{"%"},
		});
		put("Expression3", new Object[][] {
			{"PrefixOp", "Expression3"},
			{"(", "Expression", ")", "Expression3"},
			{"(", "Type", ")", "Expression3"},
			{"Primary", "Selectors", "PostfixOps"},
		});
		put("Selectors", new Object[][] {
			{},
			{"Selector", "Selectors"},
		});
		put("PostfixOps", new Object[][] {
			{},
			{"PostfixOp", "PostfixOps"},
		});
		put("Primary", new Object[][] {
			{"(", "Expression", ")"},
			{"this", "ArgumentsOpt"},
			{"super", "SuperSuffix"},
			{"Literal"},
			{"new", "Creator"},
			{"QualifiedIdentifier"},
			{"QualifiedIdentifier", "IdentifierSuffix"},
			{"BasicType", "BracketsOpt", ".", "class"},
			{"void", ".", "class"},
		});
		put("IdentifierSuffix", new Object[][] {
			{"[", "]", "BracketsOpt", ".", "class"},
			{"[", "Expression", "]"},
			{"Arguments"},
			{".", "class"},
			{".", "this"},
			{".", "super", "Arguments"},
			{".", "new", "InnerCreator"},
		});
		put("PrefixOp", new Object[][] {
			{"++"},
			{"--"},
			{"!"},
			{"~"},
			{"+"},
			{"-"},
		});
		put("PostfixOp", new Object[][] {
			{"++"},
			{"--"},
		});
		put("Selector", new Object[][] {
			{".", "IDENTIFIER", "ArgumentsOpt"},
			{".", "this"},
			{".", "super", "SuperSuffix"},
			{".", "new", "InnerCreator"},
			{"[", "Expression", "]"},
		});
		put("SuperSuffix", new Object[][] {
			{"Arguments"},
			{".", "IDENTIFIER", "ArgumentsOpt"},
		});
		put("BasicType", new Object[][] {
			{"byte"},
			{"short"},
			{"char"},
			{"int"},
			{"long"},
			{"float"},
			{"double"},
			{"boolean"},
		});
		put("ArgumentsOpt", new Object[][] {
			{},
			{"Arguments"},
		});
		put("Arguments", new Object[][] {
			{"(", ")"},
			{"(", "Expressions", ")"},
		});
		put("Expressions", new Object[][] {
			{"Expression"},
			{"Expressions", ",", "Expression"},
		});
		put("BracketsOpt", new Object[][] {
			{},
			{"[", "]", "BracketsOpt"},
		});
		put("Creator", new Object[][] {
			{"QualifiedIdentifier", "ArrayCreatorRest"},
			{"QualifiedIdentifier", "ClassCreatorRest"},
		});
		put("InnerCreator", new Object[][] {
			{"IDENTIFIER", "ClassCreatorRest"}
		});
		put("ArrayCreatorRest", new Object[][] {
			{"[", "]", "BracketsOpt", "ArrayInitializer"},
			{"[", "Expression", "]", "BracketExpressions", "BracketsOpt"},
		});
		put("BracketExpressions", new Object[][] {
			{},
			{"[", "Expression", "]", "BracketExpressions"},
		});
		put("ClassCreatorRest", new Object[][] {
			{"Arguments"},
			{"Arguments", "ClassBody"},
		});
		put("ArrayInitializer", new Object[][] {
			{"{", "}"},
			{"{", "VariableInitializers", "}"},
			{"{", "VariableInitializers", ",", "}"},
		});
		put("VariableInitializers", new Object[][] {
			{"VariableInitializer"},
			{"VariableInitializers", ",", "VariableInitializer"},
		});
		put("VariableInitializer", new Object[][] {
			{"ArrayInitializer"},
			{"Expression"},
		});
		put("ParExpression", new Object[][] {
			{"(", "Expression", ")"}
		});
		put("Block", new Object[][] {
			{"{", "BlockStatements", "}"}
		});
		put("BlockStatements", new Object[][] {
			{},
			{"BlockStatement", "BlockStatements"},
		});
		put("BlockStatement", new Object[][] {
			{"LocalVariableDeclarationStatement"},
			{"ClassOrInterfaceDeclaration"},
			{"Statement"},
			{"IDENTIFIER", ":", "Statement"},
		});
		put("LocalVariableDeclarationStatement", new Object[][] {
			{"Type", "VariableDeclarators", ";"},
			{"final", "Type", "VariableDeclarators", ";"},
		});
		put("Statement", new Object[][] {
			{"Block"},
			{"if", "ParExpression", "Statement"},
			{"if", "ParExpression", "Statement", "else", "Statement"},
			{"for", "(", "ForInitOpt", ";", ";", "ForUpdateOpt", ")", "Statement"},
			{"for", "(", "ForInitOpt", ";", "Expression", ";", "ForUpdateOpt", ")", "Statement"},
			{"while", "ParExpression", "Statement"},
			{"do", "Statement", "while", "ParExpression", ";"},
			{"try", "Block", "Catches"},
			{"try", "Block", "finally", "Block"},
			{"try", "Block", "Catches", "finally", "Block"},
			{"switch", "ParExpression", "{", "SwitchBlockStatementGroups", "}"},
			{"synchronized", "ParExpression", "Block"},
			{"return", ";"},
			{"return", "Expression", ";"},
			{"throw", "Expression", ";"},
			{"break"},
			{"break", "IDENTIFIER"},
			{"continue"},
			{"continue", "IDENTIFIER"},
			{";"},
			{"StatementExpression", ";"},
			{"IDENTIFIER", ":", "Statement"},
		});
		put("Catches", new Object[][] {
			{"CatchClause"},
			{"Catches", "CatchClause"},
		});
		put("CatchClause", new Object[][] {
			{"catch", "(", "FormalParameter", ")", "Block"}
		});
		put("SwitchBlockStatementGroups", new Object[][] {
			{},
			{"SwitchBlockStatementGroup", "SwitchBlockStatementGroups"},
		});
		put("SwitchBlockStatementGroup", new Object[][] {
			{"SwitchLabel", "BlockStatements"}
		});
		put("SwitchLabel", new Object[][] {
			{"case", "ConstantExpression", ":"},
			{"default", ":"},
		});
		put("MoreStatementExpressions", new Object[][] {
			{},
			{",", "StatementExpression", "MoreStatementExpressions"},
		});
		put("ForInitOpt", new Object[][] {
			{},
			{"StatementExpression", "MoreStatementExpressions"},
			{"Type", "VariableDeclarators"},
			{"final", "Type", "VariableDeclarators"},
		});
		put("ForUpdateOpt", new Object[][] {
			{},
			{"StatementExpression", "MoreStatementExpressions"},
		});
		put("ModifiersOpt", new Object[][] {
			{},
			{"Modifier", "ModifiersOpt"},
		});
		put("Modifier", new Object[][] {
			{"public"},
			{"protected"},
			{"private"},
			{"static"},
			{"abstract"},
			{"final"},
			{"native"},
			{"synchronized"},
			{"transient"},
			{"volatile"},
			{"strictfp"},
		});
		put("VariableDeclarators", new Object[][] {
			{"VariableDeclarator"},
			{"VariableDeclarators", ",", "VariableDeclarator"},
		});
		put("VariableDeclaratorsRest", new Object[][] {
			{"VariableDeclaratorRest"},
			{"VariableDeclaratorsRest", ",", "VariableDeclarator"},
		});
		put("ConstantDeclaratorsRest", new Object[][] {
			{"ConstantDeclaratorRest"},
			{"ConstantDeclaratorsRest", ",", "ConstantDeclarator"},
		});
		put("VariableDeclarator", new Object[][] {
			{"IDENTIFIER", "VariableDeclaratorRest"}
		});
		put("ConstantDeclarator", new Object[][] {
			{"IDENTIFIER", "ConstantDeclaratorRest"}
		});
		put("VariableDeclaratorRest", new Object[][] {
			{"BracketsOpt"},
			{"BracketsOpt", "=", "VariableInitializer"},
		});
		put("ConstantDeclaratorRest", new Object[][] {
			{"BracketsOpt", "=", "VariableInitializer"}
		});
		put("VariableDeclaratorId", new Object[][] {
			{"IDENTIFIER", "BracketsOpt"}
		});
		put("ImportDeclarations", new Object[][] {
			{},
			{"ImportDeclaration", "ImportDeclarations"},
		});
		put("TypeDeclarations", new Object[][] {
			{},
			{"TypeDeclaration", "TypeDeclarations"},
		});
		put("ImportDeclaration", new Object[][] {
			{"import", "QualifiedIdentifier", ";"},
			{"import", "QualifiedIdentifier", ".", "*", ";"},
		});
		put("TypeDeclaration", new Object[][] {
			{"ClassOrInterfaceDeclaration"},
			{";"},
		});
		put("ClassOrInterfaceDeclaration", new Object[][] {
			{"ClassDeclaration"},
			{"InterfaceDeclaration"},
//			{"ModifiersOpt", "ClassDeclaration"},
//			{"ModifiersOpt", "InterfaceDeclaration"},
		});
		put("ClassDeclaration", new Object[][] {
			{"class", "IDENTIFIER", "ClassBody"},
			{"class", "IDENTIFIER", "extends", "Type", "ClassBody"},
			{"class", "IDENTIFIER", "implements", "TypeList", "ClassBody"},
			{"class", "IDENTIFIER", "extends", "Type", "implements", "TypeList", "ClassBody"},
		});
		put("InterfaceDeclaration", new Object[][] {
			{"interface", "IDENTIFIER", "InterfaceBody"},
			{"interface", "IDENTIFIER", "extends", "TypeList", "InterfaceBody"},
		});
		put("TypeList", new Object[][] {
			{"Type"},
			{"TypeList", ",", "Type"},
		});
		put("ClassBody", new Object[][] {
			{"{", "ClassBodyDeclarations", "}"}
		});
		put("ClassBodyDeclarations", new Object[][] {
			{},
			{"ClassBodyDeclaration", "ClassBodyDeclarations"},
		});
		put("InterfaceBody", new Object[][] {
			{"{", "InterfaceBodyDeclarations", "}"}
		});
		put("InterfaceBodyDeclarations", new Object[][] {
			{},
			{"InterfaceBodyDeclaration", "InterfaceBodyDeclarations"},
		});
		put("ClassBodyDeclaration", new Object[][] {
			{";"},
			{"Block"},
			{"static", "Block"},
			{"ModifiersOpt", "MemberDecl"},
		});
		put("MemberDecl", new Object[][] {
			{"MethodOrFieldDecl"},
			{"void", "IDENTIFIER", "VoidMethodDeclaratorRest"},
			{"IDENTIFIER", "ConstructorDeclaratorRest"},
			{"ClassOrInterfaceDeclaration"},
		});
		put("MethodOrFieldDecl", new Object[][] {
			{"Type", "IDENTIFIER", "MethodOrFieldRest"}
		});
		put("MethodOrFieldRest", new Object[][] {
//			{"VariableDeclaratorRest"},
			{"VariableDeclaratorRest", ";"},
			{"MethodDeclaratorRest"},
		});
		put("InterfaceBodyDeclaration", new Object[][] {
			{";"},
			{"ModifiersOpt", "InterfaceMemberDecl"},
		});
		put("InterfaceMemberDecl", new Object[][] {
			{"InterfaceMethodOrFieldDecl"},
			{"void", "IDENTIFIER", "VoidInterfaceMethodDeclaratorRest"},
			{"ClassOrInterfaceDeclaration"},
		});
		put("InterfaceMethodOrFieldDecl", new Object[][] {
			{"Type", "IDENTIFIER", "InterfaceMethodOrFieldRest"}
		});
		put("InterfaceMethodOrFieldRest", new Object[][] {
			{"ConstantDeclaratorsRest", ";"},
			{"InterfaceMethodDeclaratorRest"},
		});
		put("MethodDeclaratorRest", new Object[][] {
			{"FormalParameters", "BracketsOpt", "MethodBody"},
			{"FormalParameters", "BracketsOpt", ";"},
			{"FormalParameters", "BracketsOpt", "throws", "QualifiedIdentifierList", "MethodBody"},
			{"FormalParameters", "BracketsOpt", "throws", "QualifiedIdentifierList", ";"},
		});
		put("VoidMethodDeclaratorRest", new Object[][] {
			{"FormalParameters", "MethodBody"},
			{"FormalParameters", ";"},
			{"FormalParameters", "throws", "QualifiedIdentifierList", "MethodBody"},
			{"FormalParameters", "throws", "QualifiedIdentifierList", ";"},
		});
		put("InterfaceMethodDeclaratorRest", new Object[][] {
			{"FormalParameters", "BracketsOpt", ";"},
			{"FormalParameters", "BracketsOpt", "throws", "QualifiedIdentifierList", ";"},
		});
		put("VoidInterfaceMethodDeclaratorRest", new Object[][] {
			{"FormalParameters", ";"},
			{"FormalParameters", "throws", "QualifiedIdentifierList", ";"},
		});
		put("ConstructorDeclaratorRest", new Object[][] {
			{"FormalParameters", "MethodBody"},
			{"FormalParameters", "throws", "QualifiedIdentifierList", "MethodBody"},
		});
		put("QualifiedIdentifierList", new Object[][] {
			{"QualifiedIdentifier"},
			{"QualifiedIdentifierList", ",", "QualifiedIdentifier"},
		});
		put("FormalParameters", new Object[][] {
			{"(", ")"},
			{"(", "FormalParameter", "FormalParametersRest", ")"},
		});
		put("FormalParametersRest", new Object[][] {
			{},
			{",", "FormalParameter", "FormalParametersRest"},
		});
		put("FormalParameter", new Object[][] {
			{"Type", "VariableDeclaratorId"},
			{"final", "Type", "VariableDeclaratorId"},
		});
		put("MethodBody", new Object[][] {
			{"Block"}
		});
	}

	public static void main(String[] arguments) {
		new Java20().interpret(arguments);
	}
}
