/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. Mini.jj */ /*@egen*/ PARSER_BEGIN(MiniParser) package Mini; public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/ protected static JJTMiniParserState jjtree = new JJTMiniParserState(); /*@egen*/ private static Token expr_token; final static void jjtreeOpenNodeScope(Node n) {} final static void jjtreeCloseNodeScope(Node n) {((SimpleNode)n).closeNode();} } PARSER_END(MiniParser) SKIP : /* WHITE SPACE */ { " " | "\t" | "\n" | "\r" | "\f" } /* Single-line Comments */ MORE : { "--" : SINGLE_LINE_COMMENT_STATE } SPECIAL_TOKEN : { : DEFAULT } MORE : { < ~[] > } /* A program consists of a number of function declarations with a * distinguished function `main' that starts the program. */ void Program() : {/*@bgen(jjtree) Program */ ASTProgram jjtn000 = new ASTProgram(JJTPROGRAM); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/} {/*@bgen(jjtree) Program */ try { /*@egen*/ (FunDecl())* /*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } /* "FUN" Ident() "(" NameList() ")" = Expr() */ void FunDecl() : {/*@bgen(jjtree) FunDecl */ ASTFunDecl jjtn000 = new ASTFunDecl(JJTFUNDECL); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ String s; Token t; } {/*@bgen(jjtree) FunDecl */ try { /*@egen*/ t = "FUN" { jjtn000.setPosition(t.beginLine, t.beginColumn); } Ident() [ Ident() ( Ident())* ] Expr()/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ /* Body expression */ } void Expr() : {/*@bgen(jjtree) Expr */ ASTExpr jjtn000 = new ASTExpr(JJTEXPR); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ int kind=-1; int un_op=-1; } {/*@bgen(jjtree) Expr */ try { /*@egen*/ IfExpr() | LetExpr() | Term() [kind = AddOp() Expr() { jjtn000.setKind(kind); }] | un_op = UnOp() { jjtn000.setUnOp(un_op); } Expr()/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } /* * The disambiguating algorithm of JavaCC automatically binds dangling * else's to the innermost if statement. The LOOKAHEAD specification * is to tell JavaCC that we know what we are doing. */ void IfExpr() : {/*@bgen(jjtree) IfExpr */ ASTIfExpr jjtn000 = new ASTIfExpr(JJTIFEXPR); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ Token t=null; } {/*@bgen(jjtree) IfExpr */ try { /*@egen*/ t = "IF" { jjtn000.setPosition(t.beginLine, t.beginColumn); } Expr() "THEN" Expr() [ LOOKAHEAD(1) "ELSE" Expr() ] "FI"/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } void LetExpr() : {/*@bgen(jjtree) LetExpr */ ASTLetExpr jjtn000 = new ASTLetExpr(JJTLETEXPR); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ Token t=null; } {/*@bgen(jjtree) LetExpr */ try { /*@egen*/ t = "LET" { jjtn000.setPosition(t.beginLine, t.beginColumn); } (Ident() Expr())+ "IN" Expr()/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } Token FunAppl() : {/*@bgen(jjtree) FunAppl */ ASTFunAppl jjtn000 = new ASTFunAppl(JJTFUNAPPL); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ Token t=null; } {/*@bgen(jjtree) FunAppl */ try { /*@egen*/ t = Ident() { jjtn000.setPosition(t.beginLine, t.beginColumn); } [Expr() ( Expr())*] /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtreeCloseNodeScope(jjtn000); } /*@egen*/ { return t; }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } void Term(): {/*@bgen(jjtree) Term */ ASTTerm jjtn000 = new ASTTerm(JJTTERM); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ int kind=-1; } {/*@bgen(jjtree) Term */ try { /*@egen*/ Factor() [kind = MultOp() { jjtn000.setKind(kind); } Term()]/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtreeCloseNodeScope(jjtn000); } /*@egen*/ { jjtn000.setPosition(expr_token.beginLine, expr_token.beginColumn); }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } void Factor() : {/*@bgen(jjtree) Factor */ ASTFactor jjtn000 = new ASTFactor(JJTFACTOR); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ int kind=-1; } {/*@bgen(jjtree) Factor */ try { /*@egen*/ Element() [kind = CmpOp() { jjtn000.setKind(kind); } Factor()]/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtreeCloseNodeScope(jjtn000); } /*@egen*/ { jjtn000.setPosition(expr_token.beginLine, expr_token.beginColumn); }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } void Element() : {} { /* expr_token is a global variable used to remember the position of an Expr() node */ LOOKAHEAD(2) expr_token = FunAppl() | expr_token = Ident() | expr_token = Integer() | expr_token = Expr() } Token Integer() : {/*@bgen(jjtree) Integer */ ASTInteger jjtn000 = new ASTInteger(JJTINTEGER); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ int num; Token t; // Contains lexem and line/column number } {/*@bgen(jjtree) Integer */ try { /*@egen*/ t = /*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtreeCloseNodeScope(jjtn000); } /*@egen*/ { jjtn000.setValue(Integer.parseInt(t.image)); jjtn000.setPosition(t.beginLine, t.beginColumn); return t; }/*@bgen(jjtree)*/ } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } Token Ident() : {/*@bgen(jjtree) Ident */ ASTIdent jjtn000 = new ASTIdent(JJTIDENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); jjtreeOpenNodeScope(jjtn000); /*@egen*/ String name; Token t; // Contains lexem and line/column number } {/*@bgen(jjtree) Ident */ try { /*@egen*/ (t = | t = | t = | t = | t = )/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtreeCloseNodeScope(jjtn000); } /*@egen*/ { jjtn000.setName(t.image); jjtn000.setPosition(t.beginLine, t.beginColumn); return t; }/*@bgen(jjtree)*/ } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); jjtreeCloseNodeScope(jjtn000); } } /*@egen*/ } int AddOp() : { Token t=null; } { (t = | t = | t = ) { return t.kind; } } int MultOp() : { Token t=null; } { (t = | t =
| t = | t = ) { return t.kind; } } int CmpOp() : { Token t=null; } { (t = | t = | t = | t = | t = | t = ) { return t.kind; } } int UnOp() : { Token t=null; } { (t = | t = ) { return t.kind; } } TOKEN : /* Boolean and arithmetic operands */ { < GT : ">" > | < LT : "<" > | < GEQ : ">=" > | < LEQ : "<=" > | < EQ : "==" > | < NEQ : "!=" > | < NOT : "!" > | < FALSE : "FALSE" > | < TRUE : "TRUE" > | < AND : "AND" > | < OR : "OR" > | < PLUS : "+"> | < MINUS : "-"> | < MULT : "*"> | < MOD : "%"> | < DIV : "/"> | < LPAREN : "("> | < RPAREN : ")"> | < ASSIGN : "="> | < COMMA : ","> | < READ : "READ"> | < WRITE : "WRITE"> } /* Has to be and the, otherwise every string wil become an token * Who knows why ... */ TOKEN : /* LITERALS */ { < #DIGIT: ["0"-"9"] > | < #LETTER: ["a"-"z", "A"-"Z"] > | < IDENT: ( | | "_")* > | < INTEGER: ()+ > | < STRING: "\"" (~["\"", "\n", "\r"])* "\"" > }