/******************************* ***** SECTION 1 - OPTIONS ***** *******************************/ options { JAVA_UNICODE_ESCAPE = true; } /********************************* ***** SECTION 2 - USER CODE ***** *********************************/ PARSER_BEGIN(SLPTreeBuilder) public class SLPTreeBuilder { public static void main(String args[]) { SLPTreeBuilder treebuilder; if (args.length == 0) { System.out.println("SLP Tree Builder: Reading from standard input . . ."); treebuilder = new SLPTreeBuilder(System.in); } else if (args.length == 1) { System.out.println("SLP Tree Builder: Reading from file " + args[0] + " . . ."); try { treebuilder = new SLPTreeBuilder(new java.io.FileInputStream(args[0])); } catch (java.io.FileNotFoundException e) { System.out.println("SLP Tree Builder: File " + args[0] + " not found."); return; } } else { System.out.println("SLP Tree Builder: Usage is one of:"); System.out.println(" java SLPTreeBuilder < inputfile"); System.out.println("OR"); System.out.println(" java SLPTreeBuilder inputfile"); return; } try { Stm s = treebuilder.Prog(); s.interp(); } catch (ParseException e) { System.out.println(e.getMessage()); System.out.println("SLP Tree Builder: Encountered errors during parse."); } } } PARSER_END(SLPTreeBuilder) /***************************************** ***** SECTION 3 - TOKEN DEFINITIONS ***** *****************************************/ TOKEN_MGR_DECLS : { static int commentNesting=0; } SKIP : /*** Ignoring spaces/tabs/newlines ***/ { " " | "\t" | "\n" | "\r" | "\f" } SKIP : /* COMMENTS */ { "/*" { commentNesting++; } : IN_COMMENT } SKIP : { "/*" { commentNesting++; } | "*/" { commentNesting--; if (commentNesting == 0) SwitchTo(DEFAULT); } | <~[]> } TOKEN : /* Keywords and punctuation */ { < SEMIC : ";" > | < ASSIGN : ":=" > | < PRINT : "print" > | < LBR : "(" > | < RBR : ")" > | < COMMA : "," > | < PLUS_SIGN : "+" > | < MINUS_SIGN : "-" > | < MULT_SIGN : "*" > | < DIV_SIGN : "/" > } TOKEN : /* Numbers and identifiers */ { < NUM : ()+ > | < #DIGIT : ["0" - "9"] > | < ID : ()+ > | < #LETTER : ["a" - "z", "A" - "Z"] > } TOKEN : /* Anything not recognised so far */ { < OTHER : ~[] > } /*************************** * SECTION 4 - THE GRAMMAR * ***************************/ Stm Prog() : { Stm s; } { s=Stm() { return s; } } Stm Stm() : { Stm s1,s2; } { (s1=SimpleStm() [ s2=Stm() {return new CompoundStm(s1,s2);} ] ) { return s1; } } Stm SimpleStm() : { String s; Exp e; ExpList el; } { (s=Ident() e=Exp()) { return new AssignStm(s,e); } | ( el=ExpList() ) { return new PrintStm(el); } } Exp Exp() : { Exp e1,e2; int o; } { (e1=SimpleExp() [o=BinOp() e2=Exp() { return new OpExp(e1,o,e2); } ] ) { return e1; } } Exp SimpleExp() : { Stm s; Exp e; } { e=IdExp() { return e; } | e=NumExp() { return e; } | ( s=Stm() e=Exp() ) { return new EseqExp(s,e); } } String Ident() : { Token t; } { t= { return t.image; } } IdExp IdExp() : { Token t; } { t= { return new IdExp(t.image); } } NumExp NumExp() : { Token t; } { t= { return new NumExp(Integer.parseInt(t.image)); } } ExpList ExpList() : { Exp e; ExpList el; } { (e=Exp() [ el=ExpList() { return new PairExpList(e,el); } ] ) { return new LastExpList(e); } } int BinOp() : {} { { return 1; } | { return 2; } | { return 3; } | { return 4; } }