/* * Classe que trata sobre os procedimetos definidos pelo utilizador... */ package Portugol.Language.Calcular; import Portugol.Language.Criar.NodeInstruction; import Portugol.Language.Analisador.Keyword; import Portugol.Language.Utilitario.LanguageException; import java.util.StringTokenizer; import java.util.Vector; /** * @author Augusto Bilabila 05-02-2012 */ public class Procedimento { public static String VERSION = "Versão:2.0 \t(c)Augusto Bilabila e David Silva Barrera"; private String algol = "", Novoalgol = ""; Vector acumulaProced = new Vector(); Vector acumulaInst = new Vector(); Vector acumulaSimb = new Vector(); int contInst = 0; byte controlaProc = 0; String strInteiro = "", strReal = "", strLiteral = "", strLogico = "", strCaracter = ""; public Procedimento(String programa) { algol = programa; } public String getNovoalgol() { return Novoalgol; } public void setNovoalgol(String Novoalgol) { this.Novoalgol = Novoalgol; } public String getAlgol() { return algol; } public void setAlgol(String algol) { this.algol = algol; } public String VariaveisTipo(String var) { int av = -1; av = strInteiro.indexOf(var); if (av != -1) { return "inteiro "; } av = strReal.indexOf(var); if (av != -1) { return "real "; } av = strLiteral.indexOf(var); if (av != -1) { return "literal "; } av = strLogico.indexOf(var); if (av != -1) { return "logica "; } // av = strCaracter.indexOf(var); if (av != -1) { return "char "; } return "N"; } //-------------------------------------------------------------------- public String RemoverCaract(String str) { str = str.replace(',', ' '); str = str.replace(')', ' '); str = str.trim(); return str; } //-------------------------------------------------------------------- public String RemoveAspas(String str) { int pos = 0, qtd1 = 0; String str1 = ""; for (int i = 0; i < str.length(); i++) { String a = "" + str.charAt(i); if (a.endsWith("\"")) { qtd1++; } if (qtd1 == 1) { str1 += str.charAt(i); } } if (str1.length() > 1) { String simbolo = "*%-%*" + contInst; str1 = str1.replace("\"", ""); str = str.replace(str1, simbolo); acumulaInst.add(str1); acumulaSimb.add(simbolo); contInst++; } return str; } //-------------------------------------------------------------------- public String DevolveAspas(String str) { for (int i = 0; i < acumulaSimb.size(); i++) { int k = str.indexOf("" + acumulaSimb.get(i)); if (k != -1) { str = str.replace("" + acumulaSimb.get(i), "" + acumulaInst.get(i)); } } return str; } //---------- Metodo que substitui o valor do argumento no parametro -------- public String SubstituirVar(String var1, String var2, String instrucao) { var1 = (var1.substring(var1.indexOf(" "))).trim(); StringTokenizer st = new StringTokenizer(instrucao, "\n"); NodeInstruction node = null; String linha = ""; String straux = "", instrucaoaux = ""; while (st.hasMoreTokens()) { linha = st.nextToken(); node = new NodeInstruction(linha, 0, 0); instrucaoaux += RemoveAspas(node.GetText()) + "\n"; } for (int i = 0; i < instrucaoaux.length(); i++) { String a = "" + instrucaoaux.charAt(i); if (a.equals(" ")) { straux = ""; } else { straux += a; } straux = straux.trim(); if (straux.equals(var1)) { instrucaoaux = instrucaoaux.replace(straux, var2); } } return instrucaoaux; } //-------------------------------------------------------------------------- public void VerOcorrencia_proccedure() throws LanguageException { for (int i = 0; i < acumulaProced.size(); i++) { for (int j = 0; j < acumulaProced.size(); j++) { if (i != j) { if ((subst("" + acumulaProced.get(i))).equals((subst("" + acumulaProced.get(j))))) { throw new LanguageException( " O COMPILADOR DETECTOU PROCEDIMENTOS COM O MESMO NOME\n", "DEVE MUDAR O NOME DO DESTE PROCEDIMENTO: " + acumulaProced.get(i) + ""); } } } } } //-------------------------------------------------------------------------- public String subst(String str) { str = str.substring(0, str.indexOf("(")); return str; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public String Tratar_Procedimento() throws LanguageException { StringTokenizer st = new StringTokenizer(getAlgol(), "\n\r"); NodeInstruction node = null; String linha = ""; String str = "", str1 = ""; Vector instrucpro = new Vector(); int cont = 0, contapro = 0; while (st.hasMoreTokens()) { linha = st.nextToken(); node = new NodeInstruction(linha, 0, 0); if (controlaProc == 1) { if (node.GetType() == Keyword.DESCONHECIDO) { str = node.GetText(); int index = acumulaProced.indexOf(str); if (index != -1 && cont == 2) { algol = algol.replace(str, "" + instrucpro.get(index)); } else { if (str.indexOf('(') != -1) { int t = 0; String sta = "", stb = "", st3 = "", param1 = ""; sta = str.substring(0, str.indexOf('(')); for (int i = 0; i < acumulaProced.size(); i++) { if (("" + acumulaProced.get(i)).startsWith(sta)) { t = 1; st3 = "" + acumulaProced.get(i); // guarda a instrucao i = acumulaProced.size(); } } if (t != 1) { throw new LanguageException(node.GetCharNum(), node.GetText(), " ESTE PROCEDIMENTO É UNEXISTENTE", "TENTA VERIFICAR BEM NOME DO PROCEDIMENTO " + sta + "\nOU SE POSSUE ALGUM PARAMETRO"); } stb = st3.substring(str.indexOf('(')); // tira os parametros na declaracao param1 = str.substring(str.indexOf('(')); // tira os argumentos na utilizacao int p1 = 0, p2 = 0; for (int i = 0; i < stb.length(); i++) { if (stb.charAt(i) == ',') { p1++; } } for (int i = 0; i < param1.length(); i++) { if (param1.charAt(i) == ',') { p2++; } } if (p1 != p2) { throw new LanguageException(node.GetCharNum(), node.GetText(), " NUMERO DE ARGUMENTO INCORRECTO", "VERIFICA COMO CONSTRUIU ESTE PROCEDIMENTO (" + sta + "), QUANTO AO PARÁMETRO"); } else { String strp = "", strp1 = ""; int v1 = 0, i1 = 1, i2 = 1; String inst = ""; do { for (int i = i1; i < stb.length(); i++) { if (stb.charAt(i) != ',' || stb.charAt(i) != ')') { strp += stb.charAt(i); } if (stb.charAt(i) == ',' || stb.charAt(i) == ')') { v1++; i1 = i + 1; i = stb.length(); //forca o termino do ciclo } } for (int f = i2; f < param1.length(); f++) { if (param1.charAt(f) != ',' || param1.charAt(f) != ')') { strp1 += param1.charAt(f); } if (param1.charAt(f) == ',' || param1.charAt(f) == ')') { i2 = f + 1; f = param1.length(); //forca o termino do ciclo } } strp = RemoverCaract(strp); strp1 = RemoverCaract(strp1); String tipo = VariaveisTipo(strp1); //retorna o tipo da variavel if (!strp.startsWith(tipo)) //verifica se o argumento tem um tipo diferente do parametro { throw new LanguageException(node.GetCharNum(), node.GetText(), " O TIPO DE DADO DO ARGUMENTO NÃO É COMPATIVEL COM O PARÂMETRO", "VERIFICA COMO ESTÁ DEFINIDO OS PARAMETROS DO PROCEDIMENTO (" + sta + ")"); } //Substituir as variaveis do procedimento(parametro) index = -1; for (int j = 0; j < acumulaProced.size(); j++) { String a = "" + acumulaProced.get(j); if (a.startsWith(sta)) { index = j; } } if (index != -1 && cont == 2) { inst = "" + instrucpro.get(index); } inst = (SubstituirVar(strp, strp1, inst)); //inst = inst.replace("\"", ""); instrucpro.set(index, inst); inst = (DevolveAspas(inst)); strp = ""; strp1 = ""; } while (v1 <= p1); inst = (DevolveAspas(inst)); instrucpro.set(index, inst); algol = algol.replace(str, "" + instrucpro.get(index)); } } } } } //----------------- Tipo de dado Primitivo ---------------------- if (node.GetType() == Keyword.DEFINIR) { String stri = "" + node.GetText(); // separa as variaveis por tipo int contInt = stri.indexOf("inteiro "); int contFloat = stri.indexOf("real "); int contString = stri.indexOf("literal "); int contChar = stri.indexOf("caracter "); int contBoolean = stri.indexOf("logico "); if (contInt != -1) { strInteiro += stri; } if (contFloat != -1) { strReal += stri; } if (contString != -1) { strLiteral += stri; } if (contChar != -1) { strLogico += stri; } if (contBoolean != -1) { strCaracter += stri; } } //------------------------------------------------------------------ if (node.GetType() == Keyword.INICIO) { VerOcorrencia_proccedure(); } //***************************************************************** if (cont == 1 && (node.GetType() != Keyword.FIMPROCEDIMENTO)) { str1 += node.GetText() + "\n"; } //***************************************************************** if (cont == 2) { instrucpro.add(str1 + "\n"); str1 = ""; } if (node.GetType() == Keyword.PROCEDIMENTO) { String algolAux = algol.substring(0, algol.indexOf("inicio")); algol = algol.replace(algolAux, "+00+00"); // muda temporariamente o algoritmo str = node.GetText(); acumulaProced.add((str.substring(12)).trim()); // guarda o nome do procedimento algolAux = algolAux.replace("procedimento ", "//procedimento "); // faz a alteracao algol = algol.replace("+00+00", algolAux); // volta no algoritmo anterior ja com a mudanca cont = 1; contapro++; } //****************************************************************** if (node.GetType() == Keyword.FIMPROCEDIMENTO) { algol = algol.replace("fimprocedimento", "fimprocedimento*/"); cont = 2; controlaProc = 1; } } // Retira o excesso do procedimento para torna-la mais leve if (algol.contains("procedimento")) { algol = algol.replace(algol.substring(algol.indexOf("//procedimento"), algol.indexOf("inicio") - 2), ""); algol = algol.replace(" inicio", "\ninicio"); // DEVO ENCONTRAR UMA SOLUÇÃO MELHOR (01-02-2014) algol = algol.replaceFirst(algol.substring((algol.indexOf("inicio") - 2), algol.indexOf("inicio")), ""); } return algol; } }