//CodeGenerator
import gi.*;

class CodeGenerator extends LL1_Grammar {

	CodeGenerator() throws Exception {
		put("LITERAL", expression("[[:digit:]]+"));
		put("IDENTIFIER", expression("[[:alpha:]]+"));
		put("RELOP", expression("<|==|>|>=|!=|<="));
		put("SPACE", expression("[[:space:]]+"));

		// /*\semantics*/semantic specification/*\off*/
//CodeGenerator.StmtList
		put("StmtList", new Object[][] {
			{},
			{"Stmt", "StmtList"},
		});
//CodeGenerator.Stmt.assign
/*\semantics*/		Semantics store = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      store " + t.child[l-3].value);
			}
		};
/*\off*/		put("Stmt", new Object[][] {
			{"IDENTIFIER", ":=", "E", /*\semantics*/store, /*\off*/";"}
		});
//CodeGenerator.Stmt.loop
/*\semantics*/		Semantics labelTop = new Semantics() {
			int label = 0;

			public void f(ParseTree t, int l) {
				System.out.println("top" + ++label + ":");
				t.value = label;
			}
		};
		Semantics comp_branch = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      comp");
				String relop = (String)t.child[l-2].value;
				System.out.print(
					relop.equals("<") ? "      bge" :
					relop.equals("==") ? "      bne" :
					relop.equals(">") ? "      ble" :
					relop.equals(">=") ? "      blt" :
					relop.equals("!=") ? "      beq" : "      bgt"
				);
			}
		};
		Semantics end = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println(" end" + t.value);
			}
		};
		Semantics gotoTop_labelEnd = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      goto top" + t.value);
				System.out.println("end" + t.value + ":");
			}
		};
/*\off*/		put("Stmt", new Object[][] {
			{/*\semantics*/labelTop, /*\off*/"while", "Condition", /*\semantics*/end, /*\off*/"loop",
				"StmtList", /*\semantics*/gotoTop_labelEnd, /*\off*/"end", "loop", ";"},
		});
		put("Condition", new Object[][] {
			{"E", "RELOP", "E"/*\semantics*/, comp_branch/*\off*/}
		});
//CodeGenerator.E
/*\semantics*/		Semantics add = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      add");
			}
		};
/*\off*/		put("E", new Object[][] {
			{"T", "E'"}
		});
		put("E'", new Object[][] {
			{},
			{"+", "T", /*\semantics*/add, /*\off*/"E'"},
		});
//CodeGenerator.T
/*\semantics*/		Semantics mult = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      mult");
			}
		};
/*\off*/		put("T", new Object[][] {
			{"F", "T'"}
		});
		put("T'", new Object[][] {
			{},
			{"*", "F", /*\semantics*/mult, /*\off*/"T'"},
		});
//CodeGenerator.F
/*\semantics*/		Semantics lc = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      lc " + t.child[l-1].value);
			}
		};
		Semantics load = new Semantics() {
			public void f(ParseTree t, int l) {
				System.out.println("      load " + t.child[l-1].value);
			}
		};
/*\off*/		put("F", new Object[][] {
			{"LITERAL"/*\semantics*/, lc/*\off*/},
			{"IDENTIFIER"/*\semantics*/, load/*\off*/},
			{"(", "E", ")"},
		});
//CodeGenerator
	}

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