package syntax; import syntax.ast.*; // définition de l'AST action code {: /* Classes utilitaires pour construction de paires de listes. * Construction iterative : * xb=new XBody(); * ( xb.field1.add(x1) ou xb.field2.add(x2); )* * new NodeAst( ..., xb.field1, xb.field2, ...); */ class KlassBody { /* (Variable|Method)* -> {Variable*,Method*} */ AstList vars; AstList methods; KlassBody() {this.vars=new AstList<>(); this.methods=new AstList<>(); } } class MethBody { /* (Variable|Stmt)* -> {Variable*,Stmt*} */ AstList vars; AstList stmts; MethBody() {this.vars=new AstList<>(); this.stmts=new AstList<>(); } } :}; /* Lexèmes (Tokens) */ terminal CLASS, MAIN, OUT, PRINTLN, PUBLIC, STATIC, STRING, SYSTEM, VOID; terminal DOT, SEMI, LBRACK, RBRACK, LBRACE, RBRACE, LPAREN, RPAREN; terminal BOOLEAN, ELSE, EXTENDS, IF, INT, NEW, RETURN, WHILE; terminal AND, ASSIGN, LESS, MINUS, NOT, PLUS, TIMES, COMMA; /* Lexèmes avec valeur sémantique */ terminal Integer LIT_INT; terminal Boolean LIT_BOOL; terminal String IDENT; /* Variables de la grammaire et Arbre de syntaxe */ nonterminal Axiom axiom; nonterminal KlassMain klassMain; nonterminal Ident ident; nonterminal AstList klassList; nonterminal Klass klass; nonterminal Ident parent; nonterminal KlassBody klassBody; // helper class pour double liste nonterminal Method method; nonterminal MethBody methBody; // helper class pour double liste nonterminal Type type; nonterminal Variable variable; nonterminal Formal formal; nonterminal AstList formals, formals1; nonterminal AstList args, args1; nonterminal Stmt stmt; nonterminal Expr expr; /* Associativités et Priorités */ precedence right ASSIGN; /* prec 1 */ precedence left AND; /* prec 4 */ precedence left LESS; /* prec 9 */ precedence left PLUS, MINUS; /* prec 11 */ precedence left TIMES; /* prec 12 */ precedence right NOT; /* prec 13 */ precedence left DOT, LBRACK, RBRACK, LPAREN, RPAREN; /* prec 15 */ /* Règles de Productions */ axiom ::= klassMain:a klassList:z {: RESULT = new Axiom(a, z); RESULT.addPosition(axleft, zxright); :} ; klassMain ::= CLASS:a ident:b LBRACE PUBLIC STATIC VOID MAIN LPAREN STRING LBRACK RBRACK ident:c RPAREN LBRACE stmt:d RBRACE RBRACE:z {: RESULT = new KlassMain(b, c, d); RESULT.addPosition(axleft, zxright); :} ; ident ::= IDENT:a {: RESULT = new Ident(a); RESULT.addPosition(axleft, axright); :} ; klassList ::= /* vide */ {: RESULT = new AstList<>(); :} | klassList:a klass:z {: RESULT = a; RESULT.add(z); RESULT.addPosition(axleft, zxright); :} ; klass ::= CLASS:a ident:b parent:c LBRACE klassBody:d RBRACE:z {: RESULT = new Klass(b, c, d.vars, d.methods); RESULT.addPosition(axleft, zxright); :} ; parent ::= /* vide */ {: RESULT = new Ident("Object"); :} | EXTENDS:a ident:z {: RESULT = z; RESULT.addPosition(axleft, zxright); :} ; klassBody ::= /* vide */ {: RESULT = new KlassBody(); :} | klassBody:a variable:z {: RESULT = a; RESULT.vars.add(z); :} | klassBody:a method:z {: RESULT = a; RESULT.methods.add(z); :} ; method ::= PUBLIC:a type:b ident:c LPAREN formals:d RPAREN LBRACE methBody:e RETURN expr:f SEMI RBRACE:z {: RESULT = new Method(b, c, d, e.vars, e.stmts, f); RESULT.addPosition(axleft, zxright); :} ; methBody ::= /* vide */ {: RESULT = new MethBody(); :} | methBody:a variable:z {: RESULT = a; RESULT.vars.add(z); :} | methBody:a stmt:z {: RESULT = a; RESULT.stmts.add(z); :} ; variable ::= type:a ident:b SEMI:z {: RESULT = new Variable(a, b); RESULT.addPosition(axleft, zxright); :} ; type ::= IDENT:a {: RESULT = new Type(a); RESULT.addPosition(axleft, axright); :} | INT:a {: RESULT = new Type(main.EnumType.INT); RESULT.addPosition(axleft, axright); :} | BOOLEAN:a {: RESULT = new Type(main.EnumType.BOOL); RESULT.addPosition(axleft, axright); :} ; // Listes éventuellement vides avec Virgule formal ::= type:a ident:z {: RESULT = new Formal(a, z); RESULT.addPosition(axleft, zxright); :} ; formals ::= /* vide */ {: RESULT = new AstList<>(); :} | formals1:a {: RESULT = a; RESULT.addPosition(axleft, axright); :} ; formals1 ::= formal:a {: RESULT = new AstList<>(); RESULT.add(a); RESULT.addPosition(axleft, axright); :} | formals1:a COMMA formal:z {: RESULT = a; RESULT.add(z); RESULT.addPosition(axleft, zxright); :} ; args ::= /* vide */ {: RESULT = new AstList<>(); :} | args1:a {: RESULT = a; RESULT.addPosition(axleft, axright); :} ; args1 ::= expr:a {: RESULT = new AstList<>(); RESULT.add(a); RESULT.addPosition(axleft, axright); :} | args1:a COMMA expr:z {: RESULT = a; RESULT.add(z); RESULT.addPosition(axleft, zxright); :} ; // Instructions stmt ::= SYSTEM:a DOT OUT DOT PRINTLN LPAREN expr:b RPAREN SEMI:z {: RESULT = new StmtPrint(b); RESULT.addPosition(axleft, zxright); :} | ident:a ASSIGN expr:b SEMI:z {: RESULT = new StmtAssign(a, b); RESULT.addPosition(axleft, zxright); :} | LBRACE:a methBody:b RBRACE:z {: RESULT = new StmtBlock(b.vars, b.stmts); RESULT.addPosition(axleft, zxright); :} | IF:a LPAREN expr:b RPAREN stmt:c ELSE stmt:z {: RESULT = new StmtIf(b, c, z); RESULT.addPosition(axleft, zxright); :} | WHILE:a LPAREN expr:b RPAREN stmt:z {: RESULT = new StmtWhile(b, z); RESULT.addPosition(axleft, zxright); :} ; // Expressions expr ::= LIT_INT:a {: RESULT = new ExprLiteralInt(a); RESULT.addPosition(axleft, axright); :} | LIT_BOOL:a {: RESULT = new ExprLiteralBool(a); RESULT.addPosition(axleft, axright); :} | LPAREN:a expr:b RPAREN:z {: RESULT = b; RESULT.addPosition(axleft, zxright); :} | expr:a AND expr:z {: RESULT = new ExprOpBin(a, main.EnumOper.AND, z); RESULT.addPosition(axleft, zxright); :} | expr:a LESS expr:z {: RESULT = new ExprOpBin(a, main.EnumOper.LESS, z); RESULT.addPosition(axleft, zxright); :} | expr:a PLUS expr:z {: RESULT = new ExprOpBin(a, main.EnumOper.PLUS, z); RESULT.addPosition(axleft, zxright); :} | expr:a MINUS expr:z {: RESULT = new ExprOpBin(a, main.EnumOper.MINUS, z); RESULT.addPosition(axleft, zxright); :} | expr:a TIMES expr:z {: RESULT = new ExprOpBin(a, main.EnumOper.TIMES, z); RESULT.addPosition(axleft, zxright); :} | NOT:a expr:z {: RESULT = new ExprOpUn(main.EnumOper.NOT, z); RESULT.addPosition(axleft, zxright); :} | expr:a DOT ident:b LPAREN args:c RPAREN:z {: RESULT = new ExprCall(a, b, c); RESULT.addPosition(axleft, zxright); :} | ident:a {: RESULT = new ExprIdent(a); RESULT.addPosition(axleft, axright); :} | NEW:a ident:b LPAREN RPAREN:z {: RESULT = new ExprNew(b); RESULT.addPosition(axleft, zxright); :} ; // Tableaux