grammar calculadora; @header{ import java.util.Hashtable; import java.util.ArrayList; } @members{ public String consultaTipo(Hashtable idents, String var) { String tipo = (String)idents.get(var); return tipo; } public int buscaIndice(ArrayList variaveis, String var) { return variaveis.indexOf(var); } //HashMap< String,Integer> table = new HashMap //ArrayList< String> declarations = new ArrayList } language returns [Hashtable identificadores] @init{ Hashtable tabela_in = new Hashtable(); ArrayList variaveis = new ArrayList();} : ((declaration[tabela_in,variaveis] | attrib[tabela_in,variaveis] | io) ';' )* {$identificadores = $declaration.envia_out; System.out.println($identificadores);} ; declaration [Hashtable recebe_in, ArrayList variaveis_in] returns [Hashtable envia_out, ArrayList variaveis_out] @init { String tipo = "";} : ( Type_Int { tipo = $Type_Int.text; } | Type_Real { tipo = $Type_Real.text; }) ID { String verificador = (String)recebe_in.get($ID.text); if (verificador != null) { System.out.println("Erro - Variavel ja definida: " + $ID.text); } else { $recebe_in.put($ID.text, tipo); $envia_out = $recebe_in; $variaveis_in.add($ID.text); $variaveis_out = $variaveis_in; } } ; attrib [Hashtable recebe_in, ArrayList variaveis_in] : ID '=' expression[recebe_in,variaveis_in] { String tipoEsquerdo = consultaTipo(recebe_in,$ID.text); if (!tipoEsquerdo.equals($expression.tipo)) { System.out.println("Erro de tipos!"); } else { System.out.print($expression.codigo); System.out.println("STOREG " + buscaIndice(variaveis_in, $ID.text) + "\n"); } ; io : 'ask' ID // Scanf | 'say' expression[null,null] //? imprime o ecran ; expression [Hashtable recebe_in, ArrayList variaveis_in] returns [String tipo,String codigo] : term[recebe_in,variaveis_in] {$tipo = $term.tipo; $codigo = $term.codigo;} (operatorAdd a=expression[recebe_in,variaveis_in] { if (!$term.tipo.equals($a.tipo)) { $tipo = "real"; } $codigo=$term.codigo+$a.codigo+$operatorAdd.codigo; } )? ; term [Hashtable recebe_in, ArrayList variaveis_in] returns [String tipo, String codigo] : factor[recebe_in,variaveis_in] {$tipo = $factor.tipo; $codigo = $factor.codigo;} (operatorMul b=term[recebe_in,variaveis_in] { if (!$factor.tipo.equals($b.tipo)) { $tipo = "real"; } $codigo=$factor.codigo+$b.codigo+$operatorMul.codigo; })? ; factor [Hashtable recebe_in, ArrayList variaveis_in] returns [String tipo, String codigo] : '(' expression[recebe_in,variaveis_in] ')' { $tipo = $expression.tipo; $codigo= $expression.codigo; } | value[recebe_in,variaveis_in] { $tipo = $value.tipo; $codigo= $value.codigo; } ; operatorAdd returns [String codigo] : '+' {$codigo="ADD \n";} | '-' {$codigo="SUB \n";} ; operatorMul returns [String codigo] : '*' {$codigo="MUL \n";} | 'div' {$codigo="DIV \n";} ; value [Hashtable recebe_in, ArrayList variaveis_in] returns [String tipo,String codigo] : ID { $tipo = consultaTipo(recebe_in, $ID.text); $codigo = "PUSHG "+ buscaIndice(variaveis_in, $ID.text) + "\n"; } | INT { $tipo = "int"; $codigo = "PUSHI "+ $INT.text + "\n";} | REAL { $tipo = "real"; $codigo = "PUSHF "+ $REAL.text + "\n";}; Type_Int: 'int' ; Type_Real : 'real' ; ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ; INT : '0'..'9'+ ; REAL : ('0'..'9'+)('.')('0'..'9'*) ; FLOAT : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? | '.' ('0'..'9')+ EXPONENT? | ('0'..'9')+ EXPONENT ; COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} ; WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;} ; STRING : '"' ( ESC_SEQ | ~('\\'|'"') )* '"' ; CHAR: '\'' ( ESC_SEQ | ~('\''|'\\') ) '\'' ; fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; fragment HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; fragment ESC_SEQ : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | UNICODE_ESC | OCTAL_ESC ; fragment OCTAL_ESC : '\\' ('0'..'3') ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ; fragment UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ;