options { LOOKAHEAD=1; } PARSER_BEGIN(Q3) public class Q3 { public static void main(String args[]) throws ParseException { Q3 parser = new Q3(System.in); try { String lisp_prog = parser.prog(); if (lisp_prog != null) System.out.println(lisp_prog.toString()); } catch (ParseException x) { System.out.println("Exiting."); throw x; } } } PARSER_END(Q3) /*** Ignoring whitespace ***/ SKIP : { " " | "\r" | "\n" | "\t" } /******************/ /***** TOKENS *****/ /******************/ TOKEN : /* Number = sequence of digits */ { < NUM : ()+ > | < #DIGIT : ["0" - "9"] > } TOKEN : /* Keywords NB - this must be placed before defn of identifiers */ { < IF : "if" > | < WHILE : "while" > | < ASSIGN : "=" > } TOKEN : /* Identifier = sequence of letters */ { < IDENT : ()+ > | < #LETTER : ["a" - "z", "A" - "Z"] > } TOKEN : /* Punctuation */ { < SEMIC : ";" > | < LCURL : "{" > | < RCURL : "}" > | < LBR : "(" > | < RBR : ")" > } /*************************/ /***** GRAMMAR RULES *****/ /*************************/ /***** Program *****/ String prog() : { String ans=null; } { ans=stat() { return ans; } } /***** Statements *****/ String stat() : { String sseq=null; String exval=null; Token id; } { sseq=statseq() { return "( " + sseq + " )"; } | exval=expr() sseq=stat() { return "( cond (" + exval + ") (" + sseq + ") )"; } | exval=expr() sseq=stat() { return "( do () (" + exval + ") (" + sseq + ") )"; } | id= exval=expr() { return "( setq " + id.image + " (" + exval + ") )"; } } /***** Sequence of statements *****/ String statseq() : { String st=null, sseq=null; } { st=stat() [ sseq=statseq() ] { if (sseq==null) return st; else return "( " + st + " " + sseq + " )"; } } /***** Expressions *****/ String expr() : {} { { return new String(token.image); } | { return new String(token.image); } }