import gi.*;

class Java12 extends Grammar {

	Java12() {

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

		/**
		* 19.2 Productions from section 2.3: The Syntactic Grammar
		*/
		put("Goal", new Object[][] {
			{"CompilationUnit"}
		});

		/**
		* 19.3 Productions from section 3: Lexical Structure
		*/
		put("Literal", new Object[][] {
			{"INTEGER_LITERAL"},
			{"FLOATING_POINT_LITERAL"},
			{"BOOLEAN_LITERAL"},
			{"CHARACTER_LITERAL"},
			{"STRING_LITERAL"},
			{"NULL_LITERAL"},
		});

		/**
		* 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("/")
			))
		)));

		/**
		* 19.3 Terminals from section 3.8: Identifier: [[:alpha:]_$][[:alnum:]_$]*
		*/
		put("IDENTIFIER_opt", new Object[][] {
			{},
			{"IDENTIFIER"},
		});
		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"));

		/**
		* 19.4 Productions from section 4: Types, Values, and Variables
		*/
		put("Type", new Object[][] {
			{"PrimitiveType"},
			{"ReferenceType"},
		});
		put("PrimitiveType", new Object[][] {
			{"NumericType"},
			{"boolean"},
		});
		put("NumericType", new Object[][] {
			{"IntegralType"},
			{"FloatingPointType"},
		});
		put("IntegralType", new Object[][] {
			{"byte"},
			{"short"},
			{"int"},
			{"long"},
			{"char"},
		});
		put("FloatingPointType", new Object[][] {
			{"float"},
			{"double"},
		});
		put("ReferenceType", new Object[][] {
			{"ClassOrInterfaceType"},
			{"ArrayType"},
		});
		put("ClassOrInterfaceType", new Object[][] {
			{"Name"}
		});
		put("ClassType", new Object[][] {
			{"ClassOrInterfaceType"}
		});
		put("InterfaceType", new Object[][] {
			{"ClassOrInterfaceType"}
		});
		put("ArrayType", new Object[][] {
			{"PrimitiveType", "Dims"},
			{"Name", "Dims"},
		});

		/**
		* 19.5 Productions from section 6: Names
		*/
		put("Name", new Object[][] {
			{"SimpleName"},
			{"QualifiedName"},
		});
		put("SimpleName", new Object[][] {
			{"IDENTIFIER"}
		});
		put("QualifiedName", new Object[][] {
			{"Name", ".", "IDENTIFIER"}
		});

		/**
		* 19.6 Productions from section 7: Packages
		*/
		put("CompilationUnit", new Object[][] {
			{"PackageDeclaration_opt", "ImportDeclarations_opt", "TypeDeclarations_opt"}
		});
		put("ImportDeclarations_opt", new Object[][] {
			{},
			{"ImportDeclarations"},
		});
		put("ImportDeclarations", new Object[][] {
			{"ImportDeclaration"},
			{"ImportDeclarations", "ImportDeclaration"},
		});
		put("TypeDeclarations_opt", new Object[][] {
			{},
			{"TypeDeclarations"},
		});
		put("TypeDeclarations", new Object[][] {
			{"TypeDeclaration"},
			{"TypeDeclarations", "TypeDeclaration"},
		});
		put("PackageDeclaration_opt", new Object[][] {
			{},
			{"PackageDeclaration"},
		});
		put("PackageDeclaration", new Object[][] {
			{"package", "Name", ";"}
		});
		put("ImportDeclaration", new Object[][] {
			{"SingleTypeImportDeclaration"},
			{"TypeImportOnDemandDeclaration"},
		});
		put("SingleTypeImportDeclaration", new Object[][] {
			{"import", "Name", ";"}
		});
		put("TypeImportOnDemandDeclaration", new Object[][] {
			{"import", "Name", ".", "*", ";"}
		});
		put("TypeDeclaration", new Object[][] {
			{"ClassDeclaration"},
			{"InterfaceDeclaration"},
			{";"},
		});

		/**
		* 19.7 Productions Used Only in the LALR(1) Grammar
		*/
		put("Modifiers_opt", new Object[][] {
			{},
			{"Modifiers"},
		});
		put("Modifiers", new Object[][] {
			{"Modifier"},
			{"Modifiers", "Modifier"},
		});
		put("Modifier", new Object[][] {
			{"public"},
			{"protected"},
			{"private"},
			{"static"},
			{"abstract"},
			{"final"},
			{"native"},
			{"synchronized"},
			{"transient"},
			{"volatile"},
			{"strictfp"},
		});

		/**
		* 19.8 Productions from section 8: Classes
		* 19.8.1 Productions from section 8.1: Class Declaration
		*/
		put("ClassDeclaration", new Object[][] {
			{"Modifiers_opt", "class", "IDENTIFIER", "Super_opt", "Interfaces_opt", "ClassBody"}
		});
		put("Super_opt", new Object[][] {
			{},
			{"Super"},
		});
		put("Super", new Object[][] {
			{"extends", "ClassType"}
		});
		put("Interfaces_opt", new Object[][] {
			{},
			{"Interfaces"},
		});
		put("Interfaces", new Object[][] {
			{"implements", "InterfaceTypeList"}
		});
		put("InterfaceTypeList", new Object[][] {
			{"InterfaceType"},
			{"InterfaceTypeList", ",", "InterfaceType"},
		});
		put("ClassBody_opt", new Object[][] {
			{},
			{"ClassBody"},
		});
		put("ClassBody", new Object[][] {
			{"{", "ClassBodyDeclarations_opt", "}"}
		});
		put("ClassBodyDeclarations_opt", new Object[][] {
			{},
			{"ClassBodyDeclarations"},
		});
		put("ClassBodyDeclarations", new Object[][] {
			{"ClassBodyDeclaration"},
			{"ClassBodyDeclarations", "ClassBodyDeclaration"},
		});
		put("ClassBodyDeclaration", new Object[][] {
			{"ClassMemberDeclaration"},
			{"StaticInitializer"},
			{"ConstructorDeclaration"},
			{"Block"},
		});
		put("ClassMemberDeclaration", new Object[][] {
			{"FieldDeclaration"},
			{"MethodDeclaration"},
			{"ClassDeclaration"},
			{"InterfaceDeclaration"},
		});

		/**
		* 19.8.2 Productions from section 8.3: Field Declarations
		*/
		put("FieldDeclaration", new Object[][] {
			{"Modifiers_opt", "Type", "VariableDeclarators", ";"}
		});
		put("VariableDeclarators", new Object[][] {
			{"VariableDeclarator"},
			{"VariableDeclarators", ",", "VariableDeclarator"},
		});
		put("VariableDeclarator", new Object[][] {
			{"VariableDeclaratorId"},
			{"VariableDeclaratorId", "=", "VariableInitializer"},
		});
		put("VariableDeclaratorId", new Object[][] {
			{"IDENTIFIER"},
			{"VariableDeclaratorId", "[", "]"},
		});
		put("VariableInitializer", new Object[][] {
			{"Expression"},
			{"ArrayInitializer"},
		});

		/**
		* 19.8.3 Productions from section 8.4: Method Declarations
		*/
		put("MethodDeclaration", new Object[][] {
			{"MethodHeader", "MethodBody"}
		});
		put("MethodHeader", new Object[][] {
			{"Modifiers_opt", "Type", "MethodDeclarator", "Throws_opt"},
			{"Modifiers_opt", "void", "MethodDeclarator", "Throws_opt"},
		});
		put("MethodDeclarator", new Object[][] {
			{"IDENTIFIER", "(", "FormalParameterList_opt", ")"},
			{"MethodDeclarator", "[", "]"},
		});
		put("FormalParameterList_opt", new Object[][] {
			{},
			{"FormalParameterList"},
		});
		put("FormalParameterList", new Object[][] {
			{"FormalParameter"},
			{"FormalParameterList", ",", "FormalParameter"},
		});
		put("FormalParameter", new Object[][] {
			{"Type", "VariableDeclaratorId"},
			{"final", "Type", "VariableDeclaratorId"},
		});
		put("Throws_opt", new Object[][] {
			{},
			{"Throws"},
		});
		put("Throws", new Object[][] {
			{"throws", "ClassTypeList"}
		});
		put("ClassTypeList", new Object[][] {
			{"ClassType"},
			{"ClassTypeList", ",", "ClassType"},
		});
		put("MethodBody", new Object[][] {
			{"Block"},
			{";"},
		});

		/**
		* 19.8.4 Productions from section 8.5: Static Initializers
		*/
		put("StaticInitializer", new Object[][] {
			{"static", "Block"}
		});

		/**
		* 19.8.5 Productions from section 8.6: Constructor Declarations
		*/
		put("ConstructorDeclaration", new Object[][] {
			{"Modifiers_opt", "ConstructorDeclarator", "Throws_opt", "ConstructorBody"}
		});
		put("ConstructorDeclarator", new Object[][] {
			{"SimpleName", "(", "FormalParameterList_opt", ")"}
		});
		put("ConstructorBody", new Object[][] {
			{"{", "ExplicitConstructorInvocation_opt", "BlockStatements_opt", "}"}
		});
		put("ExplicitConstructorInvocation_opt", new Object[][] {
			{},
			{"ExplicitConstructorInvocation"},
		});
		put("ExplicitConstructorInvocation", new Object[][] {
			{"this", "(", "ArgumentList_opt", ")", ";"},
			{"super", "(", "ArgumentList_opt", ")", ";"},
//			{"Primary", ".", "super", "(", "ArgumentList_opt", ")", ";"}
		});

		/**
		* 19.9 Productions from section 9: Interfaces
		* 19.9.1 Productions from section 9.1: Interface Declarations
		*/
		put("InterfaceDeclaration", new Object[][] {
			{"Modifiers_opt", "interface", "IDENTIFIER", "ExtendsInterfaces_opt", "InterfaceBody"}
		});
		put("ExtendsInterfaces_opt", new Object[][] {
			{},
			{"ExtendsInterfaces"},
		});
		put("ExtendsInterfaces", new Object[][] {
			{"extends", "InterfaceType"},
			{"ExtendsInterfaces", ",", "InterfaceType"},
		});
		put("InterfaceBody", new Object[][] {
			{"{", "InterfaceMemberDeclarations_opt", "}"}
		});
		put("InterfaceMemberDeclarations_opt", new Object[][] {
			{},
			{"InterfaceMemberDeclarations"},
		});
		put("InterfaceMemberDeclarations", new Object[][] {
			{"InterfaceMemberDeclaration"},
			{"InterfaceMemberDeclarations", "InterfaceMemberDeclaration"},
		});
		put("InterfaceMemberDeclaration", new Object[][] {
			{"ConstantDeclaration"},
			{"AbstractMethodDeclaration"},
			{"ClassDeclaration"},
			{"InterfaceDeclaration"},
		});
		put("ConstantDeclaration", new Object[][] {
			{"FieldDeclaration"}
		});
		put("AbstractMethodDeclaration", new Object[][] {
			{"MethodHeader", ";"}
		});

		/**
		* 19.10 Productions from section 10: Arrays
		*/
		put("ArrayInitializer", new Object[][] {
			{"{", "VariableInitializers_opt", ",", "}"},
			{"{", "VariableInitializers_opt", "}"},
		});
		put("VariableInitializers_opt", new Object[][] {
			{},
			{"VariableInitializers"},
		});
		put("VariableInitializers", new Object[][] {
			{"VariableInitializer"},
			{"VariableInitializers", ",", "VariableInitializer"},
		});

		/**
		* 19.11 Productions from section 14: Blocks and Statements
		*/
		put("Block", new Object[][] {
			{"{", "BlockStatements_opt", "}"}
		});
		put("BlockStatements_opt", new Object[][] {
			{},
			{"BlockStatements"},
		});
		put("BlockStatements", new Object[][] {
			{"BlockStatement"},
			{"BlockStatements", "BlockStatement"},
		});
		put("BlockStatement", new Object[][] {
			{"LocalVariableDeclarationStatement"},
			{"Statement"},
			{"ClassDeclaration"},
		});
		put("LocalVariableDeclarationStatement", new Object[][] {
			{"LocalVariableDeclaration", ";"}
		});
		put("LocalVariableDeclaration", new Object[][] {
			{"Type", "VariableDeclarators"},
			{"final", "Type", "VariableDeclarators"},
		});
		put("Statement", new Object[][] {
			{"StatementWithoutTrailingSubstatement"},
			{"LabeledStatement"},
			{"IfThenStatement"},
			{"IfThenElseStatement"},
			{"WhileStatement"},
			{"ForStatement"},
		});
		put("StatementNoShortIf", new Object[][] {
			{"StatementWithoutTrailingSubstatement"},
			{"LabeledStatementNoShortIf"},
			{"IfThenElseStatementNoShortIf"},
			{"WhileStatementNoShortIf"},
			{"ForStatementNoShortIf"},
		});
		put("StatementWithoutTrailingSubstatement", new Object[][] {
			{"Block"},
			{"EmptyStatement"},
			{"ExpressionStatement"},
			{"SwitchStatement"},
			{"DoStatement"},
			{"BreakStatement"},
			{"ContinueStatement"},
			{"ReturnStatement"},
			{"SynchronizedStatement"},
			{"ThrowStatement"},
			{"TryStatement"},
		});
		put("EmptyStatement", new Object[][] {
			{";"}
		});
		put("LabeledStatement", new Object[][] {
			{"IDENTIFIER", ":", "Statement"}
		});
		put("LabeledStatementNoShortIf", new Object[][] {
			{"IDENTIFIER", ":", "StatementNoShortIf"}
		});
		put("ExpressionStatement", new Object[][] {
			{"StatementExpression", ";"}
		});
		put("StatementExpression", new Object[][] {
			{"Assignment"},
			{"PreIncrementExpression"},
			{"PreDecrementExpression"},
			{"PostIncrementExpression"},
			{"PostDecrementExpression"},
			{"MethodInvocation"},
			{"ClassInstanceCreationExpression"},
		});
		put("IfThenStatement", new Object[][] {
			{"if", "(", "Expression", ")", "Statement"}
		});
		put("IfThenElseStatement", new Object[][] {
			{"if", "(", "Expression", ")", "StatementNoShortIf", "else", "Statement"}
		});
		put("IfThenElseStatementNoShortIf", new Object[][] {
			{"if", "(", "Expression", ")", "StatementNoShortIf", "else", "StatementNoShortIf"}
		});
		put("SwitchStatement", new Object[][] {
			{"switch", "(", "Expression", ")", "SwitchBlock"}
		});
		put("SwitchBlock", new Object[][] {
			{"{", "SwitchBlockStatementGroups_opt", "SwitchLabels_opt", "}"}
		});
		put("SwitchBlockStatementGroups_opt", new Object[][] {
			{},
			{"SwitchBlockStatementGroups"},
		});
		put("SwitchBlockStatementGroups", new Object[][] {
			{"SwitchBlockStatementGroup"},
			{"SwitchBlockStatementGroups", "SwitchBlockStatementGroup"},
		});
		put("SwitchBlockStatementGroup", new Object[][] {
			{"SwitchLabels", "BlockStatements"}
		});
		put("SwitchLabels_opt", new Object[][] {
			{},
			{"SwitchLabels"},
		});
		put("SwitchLabels", new Object[][] {
			{"SwitchLabel"},
			{"SwitchLabels", "SwitchLabel"},
		});
		put("SwitchLabel", new Object[][] {
			{"case", "ConstantExpression", ":"},
			{"default", ":"},
		});
		put("WhileStatement", new Object[][] {
			{"while", "(", "Expression", ")", "Statement"}
		});
		put("WhileStatementNoShortIf", new Object[][] {
			{"while", "(", "Expression", ")", "StatementNoShortIf"}
		});
		put("DoStatement", new Object[][] {
			{"do", "Statement", "while", "(", "Expression", ")", ";"}
		});
		put("ForStatement", new Object[][] {
			{"for", "(", "ForInit_opt", ";", "Expression_opt", ";", "ForUpdate_opt", ")", "Statement"}
		});
		put("ForStatementNoShortIf", new Object[][] {
			{"for", "(", "ForInit_opt", ";", "Expression_opt", ";", "ForUpdate_opt", ")", "StatementNoShortIf"}
		});
		put("ForInit_opt", new Object[][] {
			{},
			{"ForInit"},
		});
		put("ForInit", new Object[][] {
			{"StatementExpressionList"},
			{"LocalVariableDeclaration"},
		});
		put("ForUpdate_opt", new Object[][] {
			{},
			{"ForUpdate"},
		});
		put("ForUpdate", new Object[][] {
			{"StatementExpressionList"}
		});
		put("StatementExpressionList", new Object[][] {
			{"StatementExpression"},
			{"StatementExpressionList", ",", "StatementExpression"},
		});
		put("BreakStatement", new Object[][] {
			{"break", "IDENTIFIER_opt", ";"}
		});
		put("ContinueStatement", new Object[][] {
			{"continue", "IDENTIFIER_opt", ";"}
		});
		put("ReturnStatement", new Object[][] {
			{"return", "Expression_opt", ";"}
		});
		put("ThrowStatement", new Object[][] {
			{"throw", "Expression", ";"}
		});
		put("SynchronizedStatement", new Object[][] {
			{"synchronized", "(", "Expression", ")", "Block"}
		});
		put("TryStatement", new Object[][] {
			{"try", "Block", "Catches"},
			{"try", "Block", "Catches_opt", "Finally"},
		});
		put("Catches_opt", new Object[][] {
			{},
			{"Catches"},
		});
		put("Catches", new Object[][] {
			{"CatchClause"},
			{"Catches", "CatchClause"},
		});
		put("CatchClause", new Object[][] {
			{"catch", "(", "FormalParameter", ")", "Block"}
		});
		put("Finally", new Object[][] {
			{"finally", "Block"}
		});

		/**
		* 19.12 Productions from section 15: Expressions
		*/
		put("Primary", new Object[][] {
			{"PrimaryNoNewArray"},
			{"ArrayCreationExpression"},
		});
		put("PrimaryNoNewArray", new Object[][] {
			{"Literal"},
			{"this"},
			{"(", "Expression", ")"},
			{"ClassInstanceCreationExpression"},
			{"FieldAccess"},
			{"MethodInvocation"},
			{"ArrayAccess"},
			{"PrimitiveType", ".", "class"},
			{"void", ".", "class"},
			{"ArrayType", ".", "class"},
			{"Name", ".", "class"},
			{"Name", ".", "this"},
		});
		put("ClassInstanceCreationExpression", new Object[][] {
			{"new", "ClassType", "(", "ArgumentList_opt", ")", "ClassBody_opt"},
			{"Primary", ".", "new", "IDENTIFIER", "(", "ArgumentList_opt", ")", "ClassBody_opt"},
		});
		put("ArgumentList_opt", new Object[][] {
			{},
			{"ArgumentList"},
		});
		put("ArgumentList", new Object[][] {
			{"Expression"},
			{"ArgumentList", ",", "Expression"},
		});
		put("ArrayCreationExpression", new Object[][] {
			{"new", "PrimitiveType", "DimExprs", "Dims_opt"},
			{"new", "ClassOrInterfaceType", "DimExprs", "Dims_opt"},
			{"new", "PrimitiveType", "Dims", "ArrayInitializer"},
			{"new", "ClassOrInterfaceType", "Dims", "ArrayInitializer"},
		});
		put("DimExprs", new Object[][] {
			{"DimExpr"},
			{"DimExprs", "DimExpr"},
		});
		put("DimExpr", new Object[][] {
			{"[", "Expression", "]"}
		});
		put("Dims_opt", new Object[][] {
			{},
			{"Dims"},
		});
		put("Dims", new Object[][] {
			{"[", "]"},
			{"Dims", "[", "]"},
		});
		put("FieldAccess", new Object[][] {
			{"Primary", ".", "IDENTIFIER"},
			{"super", ".", "IDENTIFIER"},
			{"Name", ".", "super", ".", "IDENTIFIER"},
		});
		put("MethodInvocation", new Object[][] {
			{"Name", "(", "ArgumentList_opt", ")"},
			{"Primary", ".", "IDENTIFIER", "(", "ArgumentList_opt", ")"},
			{"super", ".", "IDENTIFIER", "(", "ArgumentList_opt", ")"},
			{"Name", ".", "super", ".", "IDENTIFIER", "(", "ArgumentList_opt", ")"},
		});
		put("ArrayAccess", new Object[][] {
			{"Name", "[", "Expression", "]"},
			{"PrimaryNoNewArray", "[", "Expression", "]"},
		});
		put("PostfixExpression", new Object[][] {
			{"Primary"},
			{"Name"},
			{"PostIncrementExpression"},
			{"PostDecrementExpression"},
		});
		put("PostIncrementExpression", new Object[][] {
			{"PostfixExpression", "++"}
		});
		put("PostDecrementExpression", new Object[][] {
			{"PostfixExpression", "--"}
		});
		put("UnaryExpression", new Object[][] {
			{"PreIncrementExpression"},
			{"PreDecrementExpression"},
			{"+", "UnaryExpression"},
			{"-", "UnaryExpression"},
			{"UnaryExpressionNotPlusMinus"},
		});
		put("PreIncrementExpression", new Object[][] {
			{"++", "UnaryExpression"}
		});
		put("PreDecrementExpression", new Object[][] {
			{"--", "UnaryExpression"}
		});
		put("UnaryExpressionNotPlusMinus", new Object[][] {
			{"PostfixExpression"},
			{"~", "UnaryExpression"},
			{"!", "UnaryExpression"},
			{"CastExpression"},
		});
		put("CastExpression", new Object[][] {
			{"(", "PrimitiveType", "Dims_opt", ")", "UnaryExpression"},
			{"(", "Expression", ")", "UnaryExpressionNotPlusMinus"},
			{"(", "Name", "Dims", ")", "UnaryExpressionNotPlusMinus"},
		});
		put("MultiplicativeExpression", new Object[][] {
			{"UnaryExpression"},
			{"MultiplicativeExpression", "*", "UnaryExpression"},
			{"MultiplicativeExpression", "/", "UnaryExpression"},
			{"MultiplicativeExpression", "%", "UnaryExpression"},
		});
		put("AdditiveExpression", new Object[][] {
			{"MultiplicativeExpression"},
			{"AdditiveExpression", "+", "MultiplicativeExpression"},
			{"AdditiveExpression", "-", "MultiplicativeExpression"},
		});
		put("ShiftExpression", new Object[][] {
			{"AdditiveExpression"},
			{"ShiftExpression", "<<", "AdditiveExpression"},
			{"ShiftExpression", ">>", "AdditiveExpression"},
			{"ShiftExpression", ">>>", "AdditiveExpression"},
		});
		put("RelationalExpression", new Object[][] {
			{"ShiftExpression"},
			{"RelationalExpression", "<", "ShiftExpression"},
			{"RelationalExpression", ">", "ShiftExpression"},
			{"RelationalExpression", "<=", "ShiftExpression"},
			{"RelationalExpression", ">=", "ShiftExpression"},
			{"RelationalExpression", "instanceof", "ReferenceType"},
		});
		put("EqualityExpression", new Object[][] {
			{"RelationalExpression"},
			{"EqualityExpression", "==", "RelationalExpression"},
			{"EqualityExpression", "!=", "RelationalExpression"},
		});
		put("AndExpression", new Object[][] {
			{"EqualityExpression"},
			{"AndExpression", "&", "EqualityExpression"},
		});
		put("ExclusiveOrExpression", new Object[][] {
			{"AndExpression"},
			{"ExclusiveOrExpression", "^", "AndExpression"},
		});
		put("InclusiveOrExpression", new Object[][] {
			{"ExclusiveOrExpression"},
			{"InclusiveOrExpression", "|", "ExclusiveOrExpression"},
		});
		put("ConditionalAndExpression", new Object[][] {
			{"InclusiveOrExpression"},
			{"ConditionalAndExpression", "&&", "InclusiveOrExpression"},
		});
		put("ConditionalOrExpression", new Object[][] {
			{"ConditionalAndExpression"},
			{"ConditionalOrExpression", "||", "ConditionalAndExpression"},
		});
		put("ConditionalExpression", new Object[][] {
			{"ConditionalOrExpression"},
			{"ConditionalOrExpression", "?", "Expression", ":", "ConditionalExpression"},
		});
		put("AssignmentExpression", new Object[][] {
			{"ConditionalExpression"},
			{"Assignment"},
		});
		put("Assignment", new Object[][] {
			{"LeftHandSide", "AssignmentOperator", "AssignmentExpression"}
		});
		put("LeftHandSide", new Object[][] {
			{"Name"},
			{"FieldAccess"},
			{"ArrayAccess"},
		});
		put("AssignmentOperator", new Object[][] {
			{"="},
			{"*="},
			{"/="},
			{"%="},
			{"+="},
			{"-="},
			{"<<="},
			{">>="},
			{">>>="},
			{"&="},
			{"^="},
			{"|="},
		});
		put("Expression_opt", new Object[][] {
			{},
			{"Expression"},
		});
		put("Expression", new Object[][] {
			{"AssignmentExpression"}
		});
		put("ConstantExpression", new Object[][] {
			{"Expression"}
		});
	}

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