/********************************* Tradutor de Pascal para Java Giovani Facchini Evandro Clivatti Dall'Agnol Changelog GB para GB - arrays uni, bi, multi - record: variaveis record - bug fix lendo real para Double - outros fix **********************************/ options { IGNORE_CASE = true; FORCE_LA_CHECK = true; STATIC = false; } PARSER_BEGIN(PascalToJavaParser) import java.io.FileWriter; import java.io.BufferedWriter; import java.io.FileInputStream; import java.util.Vector; import java.util.Hashtable; class PascalToJavaParser { /** * Arquivo de saída */ public static BufferedWriter file; /** * */ public static String temp, aux; /** */ public static Token global; public boolean multi = false; public int contadim = 1; /** * Tabela contendo hashtables. Para cada posição existe uma hashtable que indica as variáveis presentes * nos métodos */ public static Vector tabelaDeSimbolos = new Vector(); public static int nivelEscopo = -1; public static int escopoMax = -1; public static Hashtable tabelaDeProcedimentos = new Hashtable(); public static Hashtable tabelaDeRegistros = new Hashtable(); /** * Esta String será utilizada para armazenar as classes que serão criadas para representar os registros. * No fim do parsing ela será escrita no arquivo para ter todas as classes presentes no mesmo arquivo. */ public static String classesDosRegistros = ""; public static void main (String args[]) throws ParseException, TokenMgrError, NumberFormatException { if (args.length != 1) { System.out.println("Usage: "); System.exit(1); } PascalToJavaParser parser = null; try { //file = new BufferedWriter(new FileWriter(args[1])); parser = new PascalToJavaParser(new FileInputStream(args[0])); } catch (Exception e) { System.err.println("Falha ao abrir arquivo"); e.printStackTrace(); System.exit(1); } /* parser propriamente dito */ parser.parseFile(); write(classesDosRegistros); try { file.close(); } catch (Exception e) { System.err.println("Sem arquivo"); e.printStackTrace(); System.exit(1); } } public static void write(String some) { try { file.write(some); System.out.print(some); } catch (Exception e) { System.err.println("Erro na escrita de saida"); e.printStackTrace(); System.exit(1); } } } /** * Essa classe armazena um conjunto de variáveis e o seu tipo * Ex: a,b,c:real */ class Variaveis { public Vector variaveis; public String tipo; public Variaveis(){ variaveis = new Vector(); } public void addVariavel(String var) { variaveis.addElement(var); } public boolean exist(String var) { return variaveis.contains(var); } public void setTipo(String tipo_) { tipo = tipo_; } public boolean isTipo(String tipo_) { return tipo.equals(tipo_); } } /** * Classe utilizada pra armazenar os elementos de um registro. */ class Record { // cada posição contém uma classe do tipo Varialveis. Cada objeto terá as variáveis de um // determinado tipo do registro. public Vector todasVariaveis; public boolean isArray; // usado quando array public String tamArray; // usado quando array public String tipoArray; // usado quando array public boolean multidim; // usado quando array public int quantdim; // usado quando array public Record() { todasVariaveis = new Vector(); multidim = false; // usado quando array quantdim = 1; // usado quando array } } PARSER_END(PascalToJavaParser) // ******************************** Espacos ************************************ SKIP : { " " | "\t" | "\n" | "\r" | "\f" } // ****************************** Comentarios ********************************** MORE : { "{" : COMENTARIO } SPECIAL_TOKEN : { "}" : DEFAULT } MORE : { < ~[] > } // ************************* Palavras Reservadas ******************************* TOKEN : { < REAL: "real" > | < INTEGER: "integer" > | < CHAR: "char" > | < IF: "if" > | < THEN: "then" > | < ELSE: "else" > | < BEGIN: "begin" > | < END: "end" > | < PROGRAM: "program" > | < TRUE: "true" > | < FALSE: "false" > | < PROCEDURE: "procedure" > | < FUNCTION: "function" > | < RETURN: "return" > | < VAR: "var" > | < CONST: "const" > | < ARRAY: "array" > | < OF: "of" > | < WHILE: "while" > | < DO: "do" > | < TO: "to" > | < BREAK: "break" > | < CONTINUE: "continue" > | < FOR: "for" > | < USES: "uses" > | < REPEAT: "repeat" > | < UNTIL: "until" > | < CASE: "case" > | < BYTE: "byte" > | < STRING: "string" > | < NOT: "not" > | < NIL: "nil" > | < LONGINT: "longint" > | < BOOLEAN: "boolean" > | < TYPE: "type" > | < RECORD: "record" > } // ********************** Separadores *************************************** TOKEN: { < LBRACKET: "[" > | < RBRACKET: "]" > | < OPEN_PAR: "(" > | < CLOSE_PAR: ")" > | < SEMICOLON: ";" > | < COMMA: "," > | < DOT: "." > | < DOTDOT: ".." > | < TWODOTS: ":" > } // ******************************* Operadores ********************************** TOKEN : { < OPADI: ( "+" | "-" ) > | < IGUAL: "=" > | < OPMULT: ( "/" | "*" | "div" | "mod" | "and" | "in" ) > | < OPREL: ( "<" | "<=" | "<>" | ">=" | ">" | "or" | "and" ) > | < ATRIB : ":=" > } // ******************************** Literais *********************************** TOKEN : { < NUM_INT: (["0"-"9"])+ > | < NUM_REAL: (["0"-"9"])+ "." (["0"-"9"])+ > | < LITERAL: "\'" (~["\'"])* "\'" > } // ************************ FUNCOES ********************************** TOKEN: { < FUNC_WRITE: "write" > | < FUNC_WRITELN: "writeln" > | < FUNC_READ: "read" > | < FUNC_READLN: "readln" > | < FUNC_LENGTH: "length" > } // ************************ Identificador ************************************* TOKEN : { < ID: ("_"|) ("_"||)* > | < #LETTER: ["a"-"z", "A"-"Z" ] > | < #DIGIT: ["0"-"9"] > } void parseFile() : {} { Programa() } // ************************************ Gramatica ***************************** void Programa() : {} { { String name = getToken(0).image; try { file = new BufferedWriter(new FileWriter(name+".java")); } catch (Exception e) { System.err.println("Falha ao criar arquivo!!"); e.printStackTrace(); System.exit(1); } write("import java.io.*;\npublic class "+name+" {\n"); write("\tpublic static void main (String args[]) {\n\t\t"+name+" programa = new "+name+"();\n\t\tprograma.begin();\n\t}\n"); } [Uses()] [Constantes()] Corpo() { write("\n}\n"); } } /* corpo do programa */ void Corpo() : { String comandos; } { Declara() /* variaveis */ Rotinas() /* rotinas */ { escopoMax=nivelEscopo; nivelEscopo=0; } {write("\tpublic void begin() {\n");} comandos = Sentencas() { write(comandos); } {write("\t}\n");} } void Constantes() : {} { ( global = {temp=global.image.toLowerCase()+" = ";} {write("\tpublic final ");} ( ( [ {temp += getToken(0).image;}] (global= { write("int "); aux = global.image; } | global= { write("double "); aux = global.image; }) ) | global= { write("String "); aux = "\""+global.image.substring(1,global.image.length()-1)+"\"";} | global= { write("boolean "); aux = global.image; } | global= { write("boolean "); aux = global.image; } ) { write(temp+aux+";\n");} )+ } /* bibliotecas podem estar separadas por ',' e depois do ultimo nome ';' */ void Uses() : {} { ( )* {write("/* Uso de bibliotecas ainda nco suportado!!!\nBibliotecas sendo omitidas. */\n");} } /* declaracao das variaveis */ void Declara() : {} { //aqui vem o type!! [ (UmaDeclaracaoType())+ ] [ { nivelEscopo++; if (tabelaDeSimbolos.size()-1 < nivelEscopo) tabelaDeSimbolos.addElement(new Hashtable()); } ( UmaDeclaracaoVar() {write("\n");} )+ ] } void UmaDeclaracaoType(): { Token token; String construcaoDosAtributos; Record registro = new Record(); String tipoDoArray = ""; String tamanhoDoArray = ""; Vector retTam = new Vector(); } { token = //(Record() | Array() ) ( (construcaoDosAtributos = Record(registro) { classesDosRegistros+= "class "+token.image.toLowerCase()+" {\n"; classesDosRegistros+=construcaoDosAtributos + "\n}\n"; tabelaDeRegistros.put(token.image.toLowerCase(), registro); } ) | ( tamanhoDoArray = ArrayTam() tipoDoArray = Tipo() { registro.isArray = true; registro.tamArray = tamanhoDoArray; registro.tipoArray = tipoDoArray; if(multi){ registro.multidim = true; registro.quantdim = contadim; contadim = 1; multi = false; } tabelaDeRegistros.put(token.image.toLowerCase(), registro); } ) ) } String Record(Record registro): { String atributos="", declaracao; } { ( declaracao = UmaDeclaracaoVariavelType(registro) { atributos+=declaracao; } )+ { return atributos; } } String UmaDeclaracaoVariavelType(Record registro): { String tipo; String variaveis; Variaveis var; } { { var = new Variaveis(); } variaveis = ListaVariaveis(var) tipo = Tipo() { var.setTipo(tipo); variaveis =tipo+" "+variaveis+ ";\n"; registro.todasVariaveis.addElement(var); return variaveis; // ------------ /* var.setTipo(tipo); // variaveis += ";"; if (tabelaDeRegistros.get(tipo)==null) { // write("\t"+tipo+" "+variaveis); } else { if( ( (registro = (Record) tabelaDeRegistros.get(tipo)) != null ) && (registro.isArray) ){ // é array if(registro.multidim){ write("\t"+registro.tipoArray); for(int chaos=0; chaos (|) ( { fim = Integer.parseInt(getToken(0).image); } | { temId = true; tempor = getToken(0).image.toLowerCase(); } ) ( // array multidimensional { multi = true; contadim+=1; } ( (|) // ( { fim = Integer.parseInt(getToken(0).image); } ( { dimensoes.addElement(getToken(0).image); } | { temId = true; dimensoes.addElement(getToken(0).image.toLowerCase()); } ) ) )* { if(temId){ retorno = "[" + tempor + " + 1]"; if (multi){ for(int i=0; i tipo = Tipo() { var.setTipo(tipo); variaveis += ";"; if (tabelaDeRegistros.get(tipo)==null) { write("\t"+tipo+" "+variaveis); } else { if( ( (registro = (Record) tabelaDeRegistros.get(tipo)) != null ) && (registro.isArray) ){ // é array if(registro.multidim){ write("\t"+registro.tipoArray); for(int chaos=0; chaos { variaveis = tok.image.toLowerCase(); var.addVariavel(variaveis); } [ {variaveis+=", ";} auxi = ListaVariaveis(var) ] { return variaveis+auxi; } } /* tipos */ String Tipo() : { Token t; String tipo; } { { return "int"; } | { return "double"; } | { return "char"; } | { return "byte"; } | [] { return "String"; } | { return "int"; } | { return "boolean"; } | t = { tipo = t.image.toLowerCase(); if (tabelaDeRegistros.get(tipo) == null) { System.err.println("Tipo de dados: \""+tipo+"\" não declarado!"); System.exit(1); } return t.image.toLowerCase(); } } /* wrapper rotinas */ void Rotinas() : {} { ( Procedimento() | Funcao() )* { write("/* Procedimentos e Funcoes em fase de teste */\n"); } } /* procedures */ void Procedimento() : { String parametros, corpo; } { { write("\tpublic void "+getToken(0).image.toLowerCase()); tabelaDeProcedimentos.put(getToken(0).image.toLowerCase(),"anything"); } parametros = Parametros() { write(parametros); } { write("{\n"); } corpo=CorpoSimples() { write(corpo); } { write("\t}\n"); } } /* functions */ void Funcao() : { String nome = "", parametros, tipo, corpo; } { { nome = getToken(0).image.toLowerCase(); tabelaDeProcedimentos.put(nome,"anything"); } parametros=Parametros() tipo=Tipo() { write ("\tpublic "+tipo+" "+nome+parametros+" {\n"); } corpo=CorpoSimples() { write(corpo+"}\n"); } } /* parametros passados as rotinas */ String Parametros() : { String parametros="()", lista; } { [ { parametros="("; } lista = ListaParametros() { parametros+=lista+")"; } {return parametros;} ] {return parametros;} } /* utilizado por Parametros() */ String ListaParametros() : { String variaveis="", tipo, saux; Vector var = new Vector(); Hashtable tmp; } { ListaDeIdentificadores(var) (tipo = Tipo() { tabelaDeSimbolos.addElement(new Hashtable()); nivelEscopo++; tmp = (Hashtable) tabelaDeSimbolos.elementAt(nivelEscopo); for(int i = 0; i 0) return variaveis+saux;//.substring(0,saux.length()-2); // else return variaveis+saux; FUNC else { if (variaveis.length() > 0) { if (variaveis.charAt(variaveis.length()-2)==',') { String ret = variaveis.substring(0,variaveis.length()-2); return ret; } else return variaveis; } else return variaveis; } } } /* utilizado por ListaParametros() */ String CountListaPar() : { String saux; } { [ saux=ListaParametros() { return saux; } ] {return ""; } } /* utilizado por ListaParametros() e CountListaId() */ void ListaDeIdentificadores(Vector var) : {} { { var.addElement(getToken(0).image.toLowerCase()); } CountListaId(var) } /* utilizado por ListaDeIdentificadores() */ void CountListaId(Vector var) : {} { [ ListaDeIdentificadores(var) ] } /* corpo de procedimentos e funcoes */ String CorpoSimples() : { String corpo; } { Declara() corpo = Sentencas() //{corpo+="}\n";} {return corpo;} } /* sequencia de comandos */ String Sentencas() : { String cmd, saux=""; } { cmd = Comando() { if (cmd!="") cmd+="\n"; } [ saux = Sentencas() ] { return cmd+saux; } } /* um comando somente, utilizado, por exemplo, em if's */ String Sentenca() : { String cmd; } { cmd = Comando() { return cmd+"\n"; } } /* os comandos propriamente ditos */ String Comando() : { String cmd="", vread="", id=""; Token aux; } { ( /* read, readln */ ((aux=|aux=) [ cmd = VarRead() {return cmd;}] ) { if (aux.image.toLowerCase().equals("readln")) { cmd = "try {\nBufferedReader br = new BufferedReader(new InputStreamReader(System.in));\nbr.readLine();\n} catch (Exception e) {\n"; cmd+= "System.err.println(\"Falha ao ler do teclado!\");\n"; cmd+= "e.printStackTrace();\nSystem.exit(1);\n}\n"; return cmd; } else { return ""; } } | /* write, writeln */ (({cmd="System.out.print";}|{cmd="System.out.println";}) [ vread = VarWrite() ]{cmd+="("+vread+");";}) | /* for */ ( aux = { id=aux.image.toLowerCase(); cmd="for ("+id+"="; } vread = Expressao() { cmd+=vread+";"; } vread = Expressao() { cmd+=id+"<="+vread+";"+id+"++) {\n"; } vread = Sentencas() { cmd+=vread+"}\n"; } ) | /* repeat */ ( { cmd+="do {\n";} vread = Sentencas() { cmd+=vread+"} while (!("; } vread = Condicao() { cmd+=vread+"));\n"; } ) | /* while */ ( { cmd="while ("; } vread = Condicao() { cmd+=vread+") {\n"; } vread = Sentencas() { cmd+=vread+"}\n"; } ) | /* if */ /* com warning mas funfa */ ( { cmd="if ("; } vread = Condicao() { cmd+=vread+")";} (( {cmd+=" {\n";} vread = Sentenca() { cmd+=vread+"}\n";} ) | ( {cmd+=" {\n";} vread = Sentencas() { cmd+=vread+"}\n";}) ) [ (( {cmd+="else {\n";} vread = Sentencas() {cmd+=vread+"}\n";}) | ( {cmd+="else {\n";} vread = Sentenca() {cmd+=vread+"}\n";}) ) ]) | /* case */ vread = Variavel() { cmd = "switch ("+vread+") {\n";} ((aux=|/*aux=|aux=|*/aux=) { //Java nao suporta switch com boolean!! Transformar em if! cmd+="case "; if (aux.image.equalsIgnoreCase("true")) { cmd+="true: {\n"; } else if (aux.image.equalsIgnoreCase("false")) { cmd+="false: {\n"; } else { if ((aux.image.length()>3)&&(aux.image.charAt(0)=='\'')) { System.err.println("Case com string nco permitido!!!"); System.exit(1); } cmd+=aux.image+": {"; } } (vread=Sentenca() | (vread=Sentencas())) {cmd+=vread+"break;\n}\n";} )* [ (vread=Sentenca() | vread=Sentencas() ) { cmd+="default: {\n"+vread+"\n}\n"; } ] { cmd+="}"; } | /* atribuicoes */ aux = vread = ComandoAux(aux.image) { if (vread.startsWith("return")) cmd = vread; else {//como nao temos clrscr apenas eliminamos if (aux.image.toLowerCase().equals("clrscr")) cmd=""; else cmd = aux.image.toLowerCase()+vread+";"; } } ) { return cmd; } } /* argumentos do write e writeln */ String VarWrite() : { String vv="", ret="", variavel=""; } { ( { vv="\""+getToken(0).image.substring(1,getToken(0).image.length()-1)+"\""; } [ { vv+="+"; } ret = VarWrite() ] { vv += ret; } | variavel = Variavel() { vv = variavel; } [ { vv+="+"; } ret = VarWrite() ] { vv += ret; } ) { return vv; } } /* argumentos do read e readln */ String VarRead() : { String var, aux=null, construcao; } { construcao = Variavel() { var="try {\n"; String[] camposRegistros;// = construcao.split("."); Vector helper = new Vector(); int lastOcurrence = 0; for (int xxx = 0; xxx VarRead() { return var; } } /* utilizado em repeat, while e if */ String Condicao() : { String cmd; } { cmd = Expressao() {return cmd; } } /* utilizado para atribuicoes e chamar funções e procedures*/ String ComandoAux(String proc) : { String exp, va=""; Token t; } { va = VariavelAux() ( exp = Expressao() { if (va.equals("")&&(tabelaDeProcedimentos.get(proc)!=null)) { return "return "+exp+";"; } else return va+"="+exp; } |t=va=VariavelAux() { return "="+t.image.toLowerCase()+va+".length();\n"; } ) | exp = Argumentos() { return exp; } } /* utilizado no case */ String Variavel() : { String var=""; Token t; } { t = var = VariavelAux() { return t.image.toLowerCase()+var; } } String VariavelAux() : { String vaux="",lista; Token t; } { [ lista = ListaDeSubscrito() vaux = VariavelAux() { return "["+lista+"]"+vaux; } | t = vaux = VariavelAux() { return "."+t.image.toLowerCase()+vaux; } | "^" vaux = VariavelAux() { return "."+vaux; } ] { return ""; } } String ListaDeSubscrito() : { String exp, lista=""; } { exp = Expressao() lista = ListaDeSubscritoAux() { return exp+lista; } } String ListaDeSubscritoAux() : { String exp, lista=""; } { [ exp=Expressao() lista=ListaDeSubscritoAux(){return ","+exp+lista;}] { return ""; } } /* expressoes (lado direito atribuicoes) */ String Expressao() : { String cmd, vaux=""; } { cmd = ExpressaoSimples() vaux = ExpressaoAux() { return cmd+vaux; } } String ExpressaoAux() : { String cmd="", vaux=""; Token taux=null; } { [(taux = |taux = ) cmd = ExpressaoSimples() vaux = ExpressaoAux()] { if (taux != null) { String bla; if (taux.image.equalsIgnoreCase("or")) return "||"+cmd+vaux; else if (taux.image.equalsIgnoreCase("and")) return "&&"+cmd+vaux; else if (taux.image.equals("=")) return "=="+cmd+vaux; else if (taux.image.equals("<>")) return "!="+cmd+vaux; else return taux.image.toLowerCase()+cmd+vaux; } else { return cmd+vaux; } } } String ExpressaoSimples() : { String cmd, vaux=""; } { cmd = Termo() vaux = ExpressaoSimplesAux() { return cmd+vaux; } } String ExpressaoSimplesAux() : { String cmd="",vaux=""; Token taux=null; } { [taux = cmd = Termo() vaux = ExpressaoSimplesAux()] { if (taux!=null) return taux.image+cmd+vaux; else return cmd+vaux; } } String Termo() : { String cmd, vaux=""; } { cmd = Fator() vaux = TermoAux() { return cmd+vaux; } } String TermoAux() : { String cmd="", vaux=""; Token taux=null; } { [taux = cmd = Fator() vaux = TermoAux()] { if (taux!=null) return taux.image+cmd+vaux; else return cmd+vaux; } } String Fator() : { String cmd; Token taux = null; } { ( taux = cmd = Fator() | cmd = Exponenciacao() ) { if (taux!=null) return taux.image+cmd; else return cmd; } } String Exponenciacao() : { String prim, exp=""; } { prim = Primario() //exp = ExpoAux() { return prim+exp; } } /* String ExpoAux() : { String exp=""; } { ["**" exp = Exponenciacao() {return "**"+exp; } ] { return exp; } }*/ String Primario() : { String some=""; Token taux = null; } { //LOOKAHEAD(2) ( //( taux = {System.err.println("ID: "+taux.image);}(LOOKAHEAD(2)some = ParametrosPassados() | some = AcessoVariavelAux()) ) ( taux = (some = FuncaoOuVariavel())) | ( some = ConstanteSemSinal() /*{System.err.println("constante sem sinal"+some);}*/) | ( some = ConstrutorDeConjunto() /*{System.err.println("construtor de conjunto"+some);}*/) | ( some = Expressao() { some="("+some+")"; } ) | ( taux = some = Primario() )//descobrir no lex o que eh _NOT, acho q eh 'not' ) { if (taux!=null) return taux.image+some; else return some; } } String FuncaoOuVariavel(): { String lista="",parametros="", acessoVar="", listaIndices=""; } { [ ( { parametros="("; } lista = ListaParametrosPassados() { parametros+=lista+")"; } {return parametros;}) //| (acessoVar = AcessoVariavelAux() {return acessoVar;}) // ( listaIndices=ListaDeExpressaoDeIndice() acessoVar = AcessoVariavelAux() { acessoVar = "["+listaIndices+"]"+acessoVar; return acessoVar;} ) | ( {listaIndices = getToken(0).image.toLowerCase();} acessoVar = AcessoVariavelAux() { acessoVar = "."+listaIndices+acessoVar; return acessoVar;} ) | ( "^" acessoVar = AcessoVariavelAux() {return acessoVar;}) //verificar!! ponteiros viram objetos assim como registros // { return acessoVar; } ] {return "";} } String ConstanteSemSinal() : { String constante=""; } { constante = NumeroSemSinal() { return constante; } | { return "\""+getToken(0).image.substring(1,getToken(0).image.length()-1)+"\"";} | { return "null"; } } String NumeroSemSinal() : { Token t; } { (t = | t = ) { return t.image; } } String ConstrutorDeConjunto() : { String lista=""; } { [lista = ListaDeDesignadorDeMembros()] { return "["+lista+"]"; } } String ListaDeDesignadorDeMembros() : { String desig, lista=""; } { desig = DesignadorDeMembro() lista = ListaDeDesigAux() { return desig+lista; } } String ListaDeDesigAux() : { String desig, lista=""; } { [ desig=DesignadorDeMembro() lista=ListaDeDesigAux() { return ","+desig+lista; }] { return ""; } } String DesignadorDeMembro() : { String exp, desig=""; } { exp = Expressao() desig = DesignadorDeMembroAux() { return exp+desig; } } String DesignadorDeMembroAux() : { String exp, desig=""; } { [".." exp = Expressao() desig = DesignadorDeMembroAux() {return ".."+exp+desig;}] { return ""; } } String AcessoVariavelAux() : { String saux, algo=""; } { //LOOKAHEAD(2) ( //{System.err.println("AcessoVariavelAux alcancado") ;} [ ( saux=ListaDeExpressaoDeIndice() algo = AcessoVariavelAux() { algo = "["+saux+"]"+algo; } ) | ( {saux = getToken(0).image.toLowerCase();} algo = AcessoVariavelAux() { algo = "."+saux+algo; } ) | ( "^" algo = AcessoVariavelAux() ) //verificar!! ponteiros viram objetos assim como registros ] ) { return algo; } } String ListaDeExpressaoDeIndice() : { String exp, lista=""; } { exp = Expressao() lista = ListaDeExpDeIndAux() { return exp+lista; } } String ListaDeExpDeIndAux() : { String exp, lista=""; } { [ exp = Expressao() lista = ListaDeExpDeIndAux(){return ","+exp+lista;}] { return ""; } } /* argumentos nas atribuicoes */ String Argumentos(): { String lista=""; } { [ lista = ListaDeArgumentos() { return "("+lista+")"; } ] { return ""; } } String ListaDeArgumentos() : { String exp, cont=""; } { exp = Expressao() cont = ContinuacaoListaDeArgumentos() { return exp+cont; } } String ContinuacaoListaDeArgumentos() : { String lista; } { [ lista = ListaDeArgumentos() { return ","+lista; } ] { return ""; } } /* String ParametrosPassados() : { String parametros="", lista; } { {System.err.println("ParametrosPassados atingido");} [ { parametros="("; } lista = ListaParametrosPassados() { parametros+=lista+")"; } {return parametros;} ] {return parametros;} } */ String ListaParametrosPassados() : { String lista=""; } { (||||) { lista=getToken(0).image.toLowerCase(); } ( (||||) { lista+="," +getToken(0).image.toLowerCase();} )* { return lista; } }