| /*@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 |
| } |
| |
| <SINGLE_LINE_COMMENT_STATE> SPECIAL_TOKEN : |
| { |
| <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT |
| } |
| |
| <SINGLE_LINE_COMMENT_STATE> 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())* |
| <EOF>/*@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() |
| |
| <LPAREN> |
| [ |
| Ident() (<COMMA> Ident())* |
| ] |
| <RPAREN> |
| |
| <ASSIGN> |
| |
| 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() <ASSIGN> 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); } |
| <LPAREN> |
| [Expr() (<COMMA> Expr())*] <RPAREN>/*@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 = <LPAREN> Expr() <RPAREN> |
| } |
| |
| 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 = <INTEGER>/*@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 = <TRUE> | t = <FALSE> | t = <READ> | t = <WRITE> | |
| t = <IDENT>)/*@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 = <PLUS> | t = <MINUS> | t = <OR>) |
| { |
| return t.kind; |
| } |
| } |
| |
| int MultOp() : |
| { |
| Token t=null; |
| } |
| { |
| (t = <MULT> | t = <DIV> | t = <MOD> | t = <AND>) |
| { |
| return t.kind; |
| } |
| } |
| |
| int CmpOp() : |
| { |
| Token t=null; |
| } |
| { |
| (t = <EQ> | t = <NEQ> | t = <LEQ> | t = <GEQ> | t = <GT> | t = <LT>) |
| { |
| return t.kind; |
| } |
| } |
| |
| int UnOp() : |
| { |
| Token t=null; |
| } |
| { |
| (t = <MINUS> | t = <NOT>) |
| { |
| 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 <IDENT> token |
| * Who knows why ... |
| */ |
| TOKEN : /* LITERALS */ |
| { |
| < #DIGIT: ["0"-"9"] > |
| | |
| < #LETTER: ["a"-"z", "A"-"Z"] > |
| | |
| < IDENT: <LETTER> (<LETTER> | <DIGIT> | "_")* > |
| | |
| < INTEGER: (<DIGIT>)+ > |
| | |
| < STRING: "\"" (~["\"", "\n", "\r"])* "\"" > |
| } |