blob: c84c831256953633374905d7975445a0685a685b [file] [log] [blame]
/*@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"])* "\"" >
}