Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- grammar Calculette;
- @members {
- private TablesSymboles tablesSymboles = new TablesSymboles();
- private int _label = 0;
- /** générateur de nom d'étiquettes */
- private int nextLabel() { return _label++; }
- }
- // lexer
- VAR : 'var' ;
- start
- : a=calcul EOF {System.out.println($a.code);};
- expr returns [ String code ]
- @init { $code = new String(); }
- : '(' k=expr ')' {$code = $k.code;}
- | '-' j=expr {$code = "PUSHI 0\n"+ $j.code + "SUB\n";}
- | a=expr '*' b=expr {$code = $a.code + $b.code + "MUL\n";}
- | c=expr '/' d=expr {$code = $c.code + $d.code + "DIV\n";}
- | g=expr '-' h=expr {$code = $g.code + $h.code + "SUB\n";}
- | e=expr '+' f=expr {$code = $e.code + $f.code + "ADD\n";}
- | id=IDENTIFIANT { $code = "PUSHG " + tablesSymboles.adresseVar($id.text) + "\n";}
- | i=ENTIER {$code = "PUSHI " + $i.text + "\n";}
- ;
- // lexer
- IDENTIFIANT : (('a'..'z' | 'A'..'Z' | '_')('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*);
- finInstruction
- : (';' | NEWLINE)
- ;
- assignation returns [ String code ]
- : a=IDENTIFIANT '=' b=expr
- {
- $code = $b.code + "STOREG " + tablesSymboles.adresseVar($a.text) + "\n";
- }
- ;
- condition returns [String code]
- : orGauche=condition 'ou' orDroite=condition { $code = $orGauche.code + $orDroite.code + "ADD\n"; }
- | andGauche=condition 'et' andDroite=condition { $code = $andGauche.code + $andDroite.code + "MUL\n"; }
- | 'non' notDroite=condition { $code = "PUSHI 0 \n" + $notDroite.code + "SUPEQ\n"; }
- | 'true' { $code = "PUSHI 1\n"; }
- | 'false' { $code = "PUSHI 0\n"; }
- | infeqGauche=expr '<=' infeqDroite=expr { $code = $infeqGauche.code + $infeqDroite.code + "INFEQ\n"; }
- | supeqGauche=expr '>=' supeqDroite=expr { $code = $supeqGauche.code + $supeqDroite.code + "SUPEQ\n"; }
- | infGauche=expr '<' infDroite=expr { $code = $infGauche.code + $infDroite.code + "INF\n"; }
- | supGauche=expr '>' supDroite=expr { $code = $supGauche.code + $supDroite.code + "SUP\n"; }
- | equalGauche=expr '==' equalDroite=expr { $code = $equalGauche.code + $equalDroite.code + "EQUAL\n"; }
- ;
- bouclewhile returns [String code]
- : 'while' '(' con=condition ')' ins=instruction
- {
- int debLabel = nextLabel();
- int finLabel = nextLabel();
- $code = "LABEL " + debLabel + "\n";
- $code += $con.code;
- $code += "JUMPF " + finLabel + "\n";
- $code += $ins.code;
- $code += "JUMP " + debLabel + "\n";
- $code += "LABEL " + finLabel + "\n";
- }
- ;
- repeatuntil returns [ String code ]
- : 'repeat' ins=blocinstructions 'until' con=condition
- {
- int debLabel = nextLabel();
- int finLabel = nextLabel();
- $code = "LABEL " + debLabel + "\n";
- $code += $ins.code;
- $code += "PUSHI 0\n";
- $code += $con.code;
- $code += "EQUAL \n";
- $code += "JUMPF " + finLabel + "\n";
- $code += "JUMP " + debLabel + "\n";
- $code += "LABEL " + finLabel + "\n";
- }
- ;
- ifelse returns [ String code ]
- @init{ boolean sinon = false;}
- : 'if' '(' con=condition ')' gauche=instruction ('else' droite=instruction {sinon = true;})?
- {
- int debLabel = nextLabel();
- int finLabel = nextLabel();
- $code += $con.code;
- $code += "JUMPF " + debLabel + "\n";
- if(sinon){
- $code += $droite.code;
- $code += "JUMP " + finLabel + "\n";
- }
- $code += "LABEL " + debLabel + "\n";
- $code += $gauche.code;
- $code += "LABEL " + finLabel + "\n";
- }
- ;
- blocinstructions returns [ String code ]
- @init { $code = new String(); $code = ""; }
- : {$code = "";} '{' (ins=instruction {$code += $ins.code;})* '}'
- ;
- instruction returns [ String code ]
- : z=expr finInstruction
- {
- $code = $z.code;
- }
- | w=assignation finInstruction
- {
- $code = $w.code;
- }
- | a=bouclewhile finInstruction
- {
- $code = $a.code;
- }
- | rep=repeatuntil finInstruction
- {
- $code = $rep.code;
- }
- | ife=ifelse finInstruction
- {
- $code = $ife.code;
- }
- | finInstruction
- {
- $code = "";
- }
- ;
- decl returns [ String code ]
- : VAR a=IDENTIFIANT finInstruction
- {
- tablesSymboles.putAdresse($a.text);
- $code = "PUSHI 0\n";
- }
- ;
- calcul returns [ String code ]
- @init{ $code = new String(); } // On initialise $code, pour ensuite l'utiliser comme accumulateur
- : (decl { $code += $decl.code; })*
- NEWLINE*
- (instruction { $code += $instruction.code; })*
- { $code += "HALT\n"; }
- ;
- NEWLINE : '\r'? '\n';
- WS : (' '|'\t')+ -> skip ;
- ENTIER : ('0'..'9')+ ;
- UNMATCH : . -> skip ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement