1*0c56280aSSorin Basca/* 2*0c56280aSSorin Basca * Licensed to the Apache Software Foundation (ASF) under one or more 3*0c56280aSSorin Basca * contributor license agreements. See the NOTICE file distributed with 4*0c56280aSSorin Basca * this work for additional information regarding copyright ownership. 5*0c56280aSSorin Basca * The ASF licenses this file to You under the Apache License, Version 2.0 6*0c56280aSSorin Basca * (the "License"); you may not use this file except in compliance with 7*0c56280aSSorin Basca * the License. You may obtain a copy of the License at 8*0c56280aSSorin Basca * 9*0c56280aSSorin Basca * http://www.apache.org/licenses/LICENSE-2.0 10*0c56280aSSorin Basca * 11*0c56280aSSorin Basca * Unless required by applicable law or agreed to in writing, software 12*0c56280aSSorin Basca * distributed under the License is distributed on an "AS IS" BASIS, 13*0c56280aSSorin Basca * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*0c56280aSSorin Basca * See the License for the specific language governing permissions and 15*0c56280aSSorin Basca * limitations under the License. 16*0c56280aSSorin Basca */ 17*0c56280aSSorin Basca 18*0c56280aSSorin Bascaoptions { 19*0c56280aSSorin Basca MULTI=true; 20*0c56280aSSorin Basca NODE_SCOPE_HOOK=true; /* Call methods on entry/exit of node */ 21*0c56280aSSorin Basca} 22*0c56280aSSorin Basca 23*0c56280aSSorin BascaPARSER_BEGIN(MiniParser) 24*0c56280aSSorin Bascapackage Mini; 25*0c56280aSSorin Basca 26*0c56280aSSorin Bascapublic class MiniParser { 27*0c56280aSSorin Basca private static Token expr_token; 28*0c56280aSSorin Basca 29*0c56280aSSorin Basca final static void jjtreeOpenNodeScope(Node n) {} 30*0c56280aSSorin Basca final static void jjtreeCloseNodeScope(Node n) {((SimpleNode)n).closeNode();} 31*0c56280aSSorin Basca} 32*0c56280aSSorin Basca 33*0c56280aSSorin BascaPARSER_END(MiniParser) 34*0c56280aSSorin Basca 35*0c56280aSSorin BascaSKIP : /* WHITE SPACE */ 36*0c56280aSSorin Basca{ 37*0c56280aSSorin Basca " " 38*0c56280aSSorin Basca| "\t" 39*0c56280aSSorin Basca| "\n" 40*0c56280aSSorin Basca| "\r" 41*0c56280aSSorin Basca| "\f" 42*0c56280aSSorin Basca} 43*0c56280aSSorin Basca 44*0c56280aSSorin Basca/* Single-line Comments 45*0c56280aSSorin Basca */ 46*0c56280aSSorin BascaMORE : 47*0c56280aSSorin Basca{ 48*0c56280aSSorin Basca "--" : SINGLE_LINE_COMMENT_STATE 49*0c56280aSSorin Basca} 50*0c56280aSSorin Basca 51*0c56280aSSorin Basca<SINGLE_LINE_COMMENT_STATE> SPECIAL_TOKEN : 52*0c56280aSSorin Basca{ 53*0c56280aSSorin Basca <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT 54*0c56280aSSorin Basca} 55*0c56280aSSorin Basca 56*0c56280aSSorin Basca<SINGLE_LINE_COMMENT_STATE> MORE : 57*0c56280aSSorin Basca{ 58*0c56280aSSorin Basca < ~[] > 59*0c56280aSSorin Basca} 60*0c56280aSSorin Basca 61*0c56280aSSorin Basca/* A program consists of a number of function declarations with a 62*0c56280aSSorin Basca * distinguished function `main' that starts the program. 63*0c56280aSSorin Basca */ 64*0c56280aSSorin Bascavoid Program() : {} 65*0c56280aSSorin Basca{ 66*0c56280aSSorin Basca (FunDecl())* 67*0c56280aSSorin Basca <EOF> 68*0c56280aSSorin Basca} 69*0c56280aSSorin Basca 70*0c56280aSSorin Basca/* "FUN" Ident() "(" NameList() ")" = Expr() 71*0c56280aSSorin Basca */ 72*0c56280aSSorin Bascavoid FunDecl() : 73*0c56280aSSorin Basca{ 74*0c56280aSSorin Basca String s; 75*0c56280aSSorin Basca Token t; 76*0c56280aSSorin Basca} 77*0c56280aSSorin Basca{ 78*0c56280aSSorin Basca t = "FUN" { jjtThis.setPosition(t.beginLine, t.beginColumn); } 79*0c56280aSSorin Basca 80*0c56280aSSorin Basca Ident() 81*0c56280aSSorin Basca 82*0c56280aSSorin Basca <LPAREN> 83*0c56280aSSorin Basca [ 84*0c56280aSSorin Basca Ident() (<COMMA> Ident())* 85*0c56280aSSorin Basca ] 86*0c56280aSSorin Basca <RPAREN> 87*0c56280aSSorin Basca 88*0c56280aSSorin Basca <ASSIGN> 89*0c56280aSSorin Basca 90*0c56280aSSorin Basca Expr() /* Body expression */ 91*0c56280aSSorin Basca} 92*0c56280aSSorin Basca 93*0c56280aSSorin Bascavoid Expr() : 94*0c56280aSSorin Basca{ 95*0c56280aSSorin Basca int kind=-1; 96*0c56280aSSorin Basca int un_op=-1; 97*0c56280aSSorin Basca} 98*0c56280aSSorin Basca{ 99*0c56280aSSorin Basca IfExpr() 100*0c56280aSSorin Basca| 101*0c56280aSSorin Basca LetExpr() 102*0c56280aSSorin Basca| 103*0c56280aSSorin Basca Term() [kind = AddOp() Expr() { jjtThis.setKind(kind); }] 104*0c56280aSSorin Basca| 105*0c56280aSSorin Basca un_op = UnOp() { jjtThis.setUnOp(un_op); } Expr() 106*0c56280aSSorin Basca} 107*0c56280aSSorin Basca 108*0c56280aSSorin Basca/* 109*0c56280aSSorin Basca * The disambiguating algorithm of JavaCC automatically binds dangling 110*0c56280aSSorin Basca * else's to the innermost if statement. The LOOKAHEAD specification 111*0c56280aSSorin Basca * is to tell JavaCC that we know what we are doing. 112*0c56280aSSorin Basca */ 113*0c56280aSSorin Bascavoid IfExpr() : 114*0c56280aSSorin Basca{ 115*0c56280aSSorin Basca Token t=null; 116*0c56280aSSorin Basca} 117*0c56280aSSorin Basca{ 118*0c56280aSSorin Basca t = "IF" { jjtThis.setPosition(t.beginLine, t.beginColumn); } 119*0c56280aSSorin Basca Expr() "THEN" Expr() [ LOOKAHEAD(1) "ELSE" Expr() ] "FI" 120*0c56280aSSorin Basca} 121*0c56280aSSorin Basca 122*0c56280aSSorin Bascavoid LetExpr() : 123*0c56280aSSorin Basca{ 124*0c56280aSSorin Basca Token t=null; 125*0c56280aSSorin Basca} 126*0c56280aSSorin Basca{ 127*0c56280aSSorin Basca t = "LET" { jjtThis.setPosition(t.beginLine, t.beginColumn); } 128*0c56280aSSorin Basca (Ident() <ASSIGN> Expr())+ "IN" Expr() 129*0c56280aSSorin Basca} 130*0c56280aSSorin Basca 131*0c56280aSSorin BascaToken FunAppl() : 132*0c56280aSSorin Basca{ 133*0c56280aSSorin Basca Token t=null; 134*0c56280aSSorin Basca} 135*0c56280aSSorin Basca{ 136*0c56280aSSorin Basca t = Ident() { jjtThis.setPosition(t.beginLine, t.beginColumn); } 137*0c56280aSSorin Basca <LPAREN> 138*0c56280aSSorin Basca [Expr() (<COMMA> Expr())*] <RPAREN> 139*0c56280aSSorin Basca { return t; } 140*0c56280aSSorin Basca 141*0c56280aSSorin Basca} 142*0c56280aSSorin Basca 143*0c56280aSSorin Bascavoid Term(): 144*0c56280aSSorin Basca{ 145*0c56280aSSorin Basca int kind=-1; 146*0c56280aSSorin Basca} 147*0c56280aSSorin Basca{ 148*0c56280aSSorin Basca Factor() [kind = MultOp() { jjtThis.setKind(kind); } Term()] 149*0c56280aSSorin Basca { jjtThis.setPosition(expr_token.beginLine, expr_token.beginColumn); } 150*0c56280aSSorin Basca} 151*0c56280aSSorin Basca 152*0c56280aSSorin Bascavoid Factor() : 153*0c56280aSSorin Basca{ 154*0c56280aSSorin Basca int kind=-1; 155*0c56280aSSorin Basca} 156*0c56280aSSorin Basca{ 157*0c56280aSSorin Basca Element() [kind = CmpOp() { jjtThis.setKind(kind); } Factor()] 158*0c56280aSSorin Basca { jjtThis.setPosition(expr_token.beginLine, expr_token.beginColumn); } 159*0c56280aSSorin Basca} 160*0c56280aSSorin Basca 161*0c56280aSSorin Bascavoid Element() #void : {} 162*0c56280aSSorin Basca{ 163*0c56280aSSorin Basca/* expr_token is a global variable used to remember the position of an Expr() node 164*0c56280aSSorin Basca*/ 165*0c56280aSSorin Basca LOOKAHEAD(2) 166*0c56280aSSorin Basca expr_token = FunAppl() 167*0c56280aSSorin Basca| 168*0c56280aSSorin Basca expr_token = Ident() 169*0c56280aSSorin Basca| 170*0c56280aSSorin Basca expr_token = Integer() 171*0c56280aSSorin Basca| 172*0c56280aSSorin Basca expr_token = <LPAREN> Expr() <RPAREN> 173*0c56280aSSorin Basca} 174*0c56280aSSorin Basca 175*0c56280aSSorin BascaToken Integer() : 176*0c56280aSSorin Basca{ 177*0c56280aSSorin Basca int num; 178*0c56280aSSorin Basca Token t; // Contains lexem and line/column number 179*0c56280aSSorin Basca} 180*0c56280aSSorin Basca{ 181*0c56280aSSorin Basca t = <INTEGER> 182*0c56280aSSorin Basca { 183*0c56280aSSorin Basca jjtThis.setValue(Integer.parseInt(t.image)); 184*0c56280aSSorin Basca jjtThis.setPosition(t.beginLine, t.beginColumn); 185*0c56280aSSorin Basca return t; 186*0c56280aSSorin Basca } 187*0c56280aSSorin Basca} 188*0c56280aSSorin Basca 189*0c56280aSSorin BascaToken Ident() : 190*0c56280aSSorin Basca{ 191*0c56280aSSorin Basca String name; 192*0c56280aSSorin Basca Token t; // Contains lexem and line/column number 193*0c56280aSSorin Basca} 194*0c56280aSSorin Basca{ 195*0c56280aSSorin Basca (t = <TRUE> | t = <FALSE> | t = <READ> | t = <WRITE> | 196*0c56280aSSorin Basca t = <IDENT>) 197*0c56280aSSorin Basca { 198*0c56280aSSorin Basca jjtThis.setName(t.image); 199*0c56280aSSorin Basca jjtThis.setPosition(t.beginLine, t.beginColumn); 200*0c56280aSSorin Basca return t; 201*0c56280aSSorin Basca } 202*0c56280aSSorin Basca} 203*0c56280aSSorin Basca 204*0c56280aSSorin Bascaint AddOp() #void : 205*0c56280aSSorin Basca{ 206*0c56280aSSorin Basca Token t=null; 207*0c56280aSSorin Basca} 208*0c56280aSSorin Basca{ 209*0c56280aSSorin Basca (t = <PLUS> | t = <MINUS> | t = <OR>) 210*0c56280aSSorin Basca { 211*0c56280aSSorin Basca return t.kind; 212*0c56280aSSorin Basca } 213*0c56280aSSorin Basca} 214*0c56280aSSorin Basca 215*0c56280aSSorin Bascaint MultOp() #void : 216*0c56280aSSorin Basca{ 217*0c56280aSSorin Basca Token t=null; 218*0c56280aSSorin Basca} 219*0c56280aSSorin Basca{ 220*0c56280aSSorin Basca (t = <MULT> | t = <DIV> | t = <MOD> | t = <AND>) 221*0c56280aSSorin Basca { 222*0c56280aSSorin Basca return t.kind; 223*0c56280aSSorin Basca } 224*0c56280aSSorin Basca} 225*0c56280aSSorin Basca 226*0c56280aSSorin Bascaint CmpOp() #void : 227*0c56280aSSorin Basca{ 228*0c56280aSSorin Basca Token t=null; 229*0c56280aSSorin Basca} 230*0c56280aSSorin Basca{ 231*0c56280aSSorin Basca (t = <EQ> | t = <NEQ> | t = <LEQ> | t = <GEQ> | t = <GT> | t = <LT>) 232*0c56280aSSorin Basca { 233*0c56280aSSorin Basca return t.kind; 234*0c56280aSSorin Basca } 235*0c56280aSSorin Basca} 236*0c56280aSSorin Basca 237*0c56280aSSorin Bascaint UnOp() #void : 238*0c56280aSSorin Basca{ 239*0c56280aSSorin Basca Token t=null; 240*0c56280aSSorin Basca} 241*0c56280aSSorin Basca{ 242*0c56280aSSorin Basca (t = <MINUS> | t = <NOT>) 243*0c56280aSSorin Basca { 244*0c56280aSSorin Basca return t.kind; 245*0c56280aSSorin Basca } 246*0c56280aSSorin Basca} 247*0c56280aSSorin Basca 248*0c56280aSSorin Basca 249*0c56280aSSorin BascaTOKEN : /* Boolean and arithmetic operands */ 250*0c56280aSSorin Basca{ 251*0c56280aSSorin Basca < GT : ">" > 252*0c56280aSSorin Basca| 253*0c56280aSSorin Basca < LT : "<" > 254*0c56280aSSorin Basca| 255*0c56280aSSorin Basca < GEQ : ">=" > 256*0c56280aSSorin Basca| 257*0c56280aSSorin Basca < LEQ : "<=" > 258*0c56280aSSorin Basca| 259*0c56280aSSorin Basca < EQ : "==" > 260*0c56280aSSorin Basca| 261*0c56280aSSorin Basca < NEQ : "!=" > 262*0c56280aSSorin Basca| 263*0c56280aSSorin Basca < NOT : "!" > 264*0c56280aSSorin Basca| 265*0c56280aSSorin Basca < FALSE : "FALSE" > 266*0c56280aSSorin Basca| 267*0c56280aSSorin Basca < TRUE : "TRUE" > 268*0c56280aSSorin Basca| 269*0c56280aSSorin Basca < AND : "AND" > 270*0c56280aSSorin Basca| 271*0c56280aSSorin Basca < OR : "OR" > 272*0c56280aSSorin Basca| 273*0c56280aSSorin Basca < PLUS : "+"> 274*0c56280aSSorin Basca| 275*0c56280aSSorin Basca < MINUS : "-"> 276*0c56280aSSorin Basca| 277*0c56280aSSorin Basca < MULT : "*"> 278*0c56280aSSorin Basca| 279*0c56280aSSorin Basca < MOD : "%"> 280*0c56280aSSorin Basca| 281*0c56280aSSorin Basca < DIV : "/"> 282*0c56280aSSorin Basca| 283*0c56280aSSorin Basca < LPAREN : "("> 284*0c56280aSSorin Basca| 285*0c56280aSSorin Basca < RPAREN : ")"> 286*0c56280aSSorin Basca| 287*0c56280aSSorin Basca < ASSIGN : "="> 288*0c56280aSSorin Basca| 289*0c56280aSSorin Basca < COMMA : ","> 290*0c56280aSSorin Basca| 291*0c56280aSSorin Basca < READ : "READ"> 292*0c56280aSSorin Basca| 293*0c56280aSSorin Basca < WRITE : "WRITE"> 294*0c56280aSSorin Basca} 295*0c56280aSSorin Basca 296*0c56280aSSorin Basca/* Has to be and the, otherwise every string wil become an <IDENT> token 297*0c56280aSSorin Basca * Who knows why ... 298*0c56280aSSorin Basca */ 299*0c56280aSSorin BascaTOKEN : /* LITERALS */ 300*0c56280aSSorin Basca{ 301*0c56280aSSorin Basca < #DIGIT: ["0"-"9"] > 302*0c56280aSSorin Basca| 303*0c56280aSSorin Basca < #LETTER: ["a"-"z", "A"-"Z"] > 304*0c56280aSSorin Basca| 305*0c56280aSSorin Basca < IDENT: <LETTER> (<LETTER> | <DIGIT> | "_")* > 306*0c56280aSSorin Basca| 307*0c56280aSSorin Basca < INTEGER: (<DIGIT>)+ > 308*0c56280aSSorin Basca| 309*0c56280aSSorin Basca < STRING: "\"" (~["\"", "\n", "\r"])* "\"" > 310*0c56280aSSorin Basca} 311