123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218 |
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package ast;
- import API.Functions;
- import common.Instruction;
- import API.Types;
- import API.Variables;
- import static ast.Semantic.current;
- import common.Log;
- import java.util.ArrayList;
- import java.util.Stack;
- /**
- *
- * @author Eugenio
- */
- public class Semantic extends Log {
- protected Stack<String> escopoStack = new Stack<>();
- protected AbstractSyntaxTree ast;
- protected static Node current;
- // protected HashMap<String, String> errosTemplate = new HashMap<>();
- // protected boolean temporalErro = false;
- public Semantic() {
- }
- public Semantic(AbstractSyntaxTree ast) {
- this.ast = ast;
- }
- /**
- * Percorre a AST em chama o metodo viSitNode que redireciona para o
- * tratamento de cada no
- *
- * @param as
- * @throws Exception
- */
- public Semantic Execute() throws Exception {
- _analise(ast.root);
- return this;
- }
- /**
- * Parte aux do metodo analiSe.
- *
- * @param n
- * @return
- * @throws Exception
- */
- protected void _analise(Node n) throws Exception {
- if (null == n) {
- return;
- }
- current = n;
- switch (current.Get("class")) {
- default:
- visitNode();
- if (!n.childrens.isEmpty()) {
- for (Node n2 : n.childrens) {
- _analise(n2);
- }
- }
- }
- }
- protected void visitNode() throws Exception {
- switch (current.Get("class")) {
- case "type":
- CheckType();
- break;
- case "selector":
- CheckSelector();
- break;
- case "def.assign":
- CheckAssign();
- break;
- case "call":
- CheckCall();
- break;
- case "dec.const":
- break;
- case "dec.type":
- break;
- // case "_array":
- //// chkArray();
- // break;
- // case "read":
- // chkRead();
- // break;
- // case "print":
- // chkPrint();
- // break;
- // case "dec::var":
- // verificarDecVariavel();
- // break;
- // case "return":
- // checkRetornoFuncao();
- // break;
- // case "var":
- // verificarVariavel(current);
- // break;
- // case "parametros::list":
- // testarListaParametros();
- // break;
- // case "op::unaria":
- // chkOperacaoUnario();
- // break;
- // case "expr::arithmetic":
- // exprArithmetic();
- // break;
- // case "exp::boolena":
- // chkOperacaoBooleano();
- // break;
- // case "dec::function":
- // case "main":
- // verificarFuncao();
- // break;
- }
- }
- protected void CheckType() {
- String type = current.Get("type");
- if (!Types.Primitive(type) && !Types.Defined(type)) {
- AddError(new Instruction()
- .Set("class", "Type")
- .Set("msg", String.format("Tipo '%s' não definido", type))
- .Set("line", current.Get("line"))
- .Set("col", current.Get("col"))
- );
- }
- }
- protected void CheckSelector() {
- try {
- String type;
- switch (current.Get("subclass")) {
- case "operand":
- if (!current.eq("classType", "value")
- && Variables.Get(current.getText()) == null) {
- throw new Exception("Variavel " + current.getText() + " não definida");
- }
- break;
- case "selector":
- type = Variables.TypeOf(current.Get("value"));
- if (type.equals("undefined")) {
- throw new Exception("Variavel " + current.getText() + " não definida");
- }
- // current.Set("type", type);
- // System.out.println("CheckSelector:" + current);
- break;
- case "index":
- // System.out.println("CheckSeletor:" + current);
- String varname = current.Get("value");
- type = Variables.TypeOf(varname);
- if (type.equals("undefined")) {
- throw new Exception("Variavel " + current.getText() + " não definida");
- }
- Node var = Variables.Get(varname);
- Node ical;
- ArrayList<Node> indexesCall = new ArrayList<>(current.childrens());
- ArrayList<Node> indexesDecl = var.childrens();
- if (indexesCall.size() > indexesDecl.size()) {
- // todo exibir os indices
- throw new Exception("Variavel " + current.getText() + " não aceita acesso indexado");
- } else {
- int idecval,
- icallval;
- for (Node idec : indexesDecl) {
- if (indexesCall.isEmpty()) {
- throw new Exception("Variavel " + current.getText() + " não aceita acesso indexado");
- }
- ical = indexesCall.remove(0);
- // se não for um indice numerico salta
- if (!ical.isNumber("value")) {
- continue;
- }
- icallval = ical.GetInt("value");
- idecval = idec.GetInt("value");
- if (idec.isNumber("value") && icallval >= idecval) {
- throw new Exception(String.format("Index ['%s'] fora do intervalo ['%s'] em %s", icallval, idecval, current.getText()));
- }
- }
- }
- break;
- }
- } catch (Exception e) {
- AddError(new Instruction()
- .Set("class", "Type")
- .Set("msg", e.getMessage())
- .Set("line", current.Get("line"))
- .Set("col", current.Get("col"))
- );
- }
- }
- protected void CheckAssign() throws Exception {
- ArrayList<String> returns = new ArrayList<>();
- Node f, funcret;
- for (Node attrib : current.childrens().get(1).childrens()) {
- switch (attrib.Class()) {
- case "call":
- f = Functions.Get(attrib.getText());
- funcret = f.find("dec.return");
- if (funcret != null) {
- for (Node r : funcret.childrens()) {
- returns.add(r.Get("type"));
- }
- }
- break;
- default:
- returns.add(attrib.Get("type"));
- break;
- }
- }
- ArrayList<Node> dsts = current.childrens().get(0).childrens();
- if (dsts.size() != returns.size()) {
- throw new Exception(String.format("Atribuição incompativel. Esperando %d e atribuido %d", dsts.size(), returns.size()));
- } else {
- int i = 0;
- String attrib, typedst;
- for (Node dst : dsts) {
- attrib = returns.get(i++);
- // typedst = dst.Get("type");
- typedst = typeoOf(dst);
- if (!typedst.equals(attrib)) {
- AddError(new Instruction()
- .Set("class", "Assing")
- .Set("msg", String.format("Tipo atribuição '%s' diferente do esperado '%s'", attrib, typedst))
- .Set("line", current.Get("line"))
- .Set("col", current.Get("col"))
- );
- }
- }
- // System.out.println("CheckAssign:" + returns);
- // A quantidade de retornos é igual a de destinos, verificar o tipo de cada atribuição
- }
- }
- protected String typeoOf(Node n) throws Exception {
- // System.out.println("TYPEOF:\n" + n.getText() + "\n[" + Variables.TypeOf(n.getText()) + "]");
- if (n.eq("type", "")) {
- // Variables.type(n.getText(), n.Get("scope"));
- n.Set("type", Variables.TypeOf(n.getText()));
- }
- return n.Get("type");
- }
- protected void CheckCall() throws Exception {
- // System.out.println("CheckCall:" + current);
- Node function = Functions.Get(current.getText());
- // Verifica se a funcao foi definida
- if (function == null) {
- AddError(new Instruction()
- .Set("class", "Call")
- .Set("msg", String.format("A função '%s' não foi definida", current.getText()))
- .Set("line", current.Get("line"))
- .Set("col", current.Get("col"))
- );
- return;
- }
- // Se a definicao contem argumentos verifica se na chamada possui o mesmo
- // numero de argumentos e se são do mesmo tipo
- ArrayList<Node> argumentsDelc = function.findAll("argument", "class");
- ArrayList<String> argsDelc = new ArrayList<>();
- String type, pointer;
- Node t;
- for (Node args : argumentsDelc) {
- t = args.find("type");
- type = t.Get("type");
- pointer = t.Get("pointer");
- for (int i = 0; i < args.find("ids").childrens().size(); i++) {
- argsDelc.add((pointer.equals("") ? "" : "&") + type);
- }
- }
- Node argumentsCall = current.find("arguments").find("exprs");
- ArrayList<String> argsCall = new ArrayList<>();
- if (argumentsCall != null) {
- String prefix = "";
- for (Node argCall : argumentsCall.childrens()) {
- // System.out.println("ArgCall:" + argCall);
- if (argCall.eq("subclass", "address") || argCall.eq("pointer", "*")) {
- prefix = "&";
- }
- argsCall.add(prefix + argCall.Get("type"));
- }
- }
- int argsDeclCount = argsDelc.size();
- int argsCallCount = argsCall.size();
- if (argsCallCount != argsDeclCount) {
- AddError(new Instruction()
- .Set("class", "Call")
- .Set("msg", String.format("Chamada incompativel. Numero de parametros de chamada é '%s' e o esperado é '%s'", argsCallCount, argsDeclCount))
- .Set("line", current.Get("line"))
- .Set("col", current.Get("col"))
- );
- } else {
- // todo check types
- int i = 0;
- String callType;
- for (String declType : argsDelc) {
- callType = argsCall.get(i++);
- // System.out.println("Call arg:" + callType + ":" + declType);
- if (!declType.equals(callType)) {
- AddError(new Instruction()
- .Set("class", "Call")
- .Set("msg", String.format("Chamada incompativel. O parâmetro %s é do tipo '%s' e o esperado é '%s'", i, callType, declType))
- .Set("line", current.Get("line"))
- .Set("col", current.Get("col"))
- );
- }
- }
- }
- }
- }
- // /**
- // * Busca uma declaração de uma função, caso não exista adiciona erro ao Log
- // *
- // * @param nomeDaFuncao
- // * @param AddError
- // * @return Node | null
- // */
- // protected static Node encontreFuncao(String id, boolean AddError) {
- // Node func = null;
- // if (id.substring(0, 2).equals("__")) {
- //
- // } else if (Functions.existe(id)) {
- // func = Functions.function(id);
- // }
- // if (func == null && AddError) {
- // AddError(Api.getFormatedPosition(current)
- // + "Chamada de função. Tentativa de chamar uma função {"
- // + id + "} não definida.");
- // }
- // return func;
- // }
- //
- // protected void chkOperacaoBooleano() {
- // Node n1 = getOperandoNaAst(current.getFilho(0), current);
- // Node n2 = getOperandoNaAst(current.getFilho(1), current);
- //
- // if (n1 == null || n2 == null) {
- // return;
- // }
- //
- // String esperado = "";
- // String tipo1 = tipo(n1);
- // String tipo2 = tipo(n2);
- //
- // if (current.in("value", new String[]{"==", "!="})) {
- // if (!tipo1.equals(tipo2)) {
- // AddError(Api.getFormatedPosition(current) + " Comparação invalida. "
- // + "Comparação entre tipos diferentes. Param[1] do tipo {" + tipo1 + "} Param[2] do tipo {" + tipo2 + "}");
- // }
- // } else {
- // if (current.in("value", new String[]{"<", ">", "<=", ">="})) {
- // esperado = "int";
- // } else if (current.in("value", new String[]{"&&", "||"})) {
- // esperado = "bool";
- // }
- // String op = current.getText();
- // tipoCheck(n1, tipo1, esperado, op);
- // tipoCheck(n2, tipo2, esperado, op);
- // }
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Operação de atribuição. -> Se o endereço de destino é valido, seja
- // * variavel ou declarcao de uma -> Se o tipo atribuido corresponde com o
- // * esperado
- // *
- // * @throws Exception
- // */
- // protected void chkAssign(Node current) throws Exception {
- // Node parent = current.parent;
- //
- // /**
- // * Se parent for igual assign::op entao deve se analisar a variavel,
- // * caso contrario sera dec::var e não precisa verificar o acesso a
- // * variavel
- // */
- // Node var;
- // boolean isDeclaracao = true;
- // if (parent.igual("class", "assign::op")) {
- // isDeclaracao = false;
- // if (Constantes.existe(parent.getText())) {
- // _addViolacaoDeConstante(parent.getText());
- // return;
- // }
- // var = parent.encontreByClass("var");
- // _analise(var);
- //
- // } else {
- // var = parent;
- // }
- //
- // /**
- // * Apos verificar variavel, vamos verificar se o tipo atribuido é igual
- // * ao esperado;
- // */
- // Node value = current.first();
- //
- // /*Se valor for uma variavel e a mesma não existir*/
- //// value.Set("verificador", "0");
- // _analise(value);
- // /*Se ocorreu erro na verificação do valor atribuido*/
- ////
- // String eTipo = parent.Get("tipo"), aTipo = tipo(value);
- //
- // if (var.igual("tipo", Types.REFERENCE)) {
- // if (isDeclaracao && value.diferente("acessoEndereco", "true")) {
- // AddError(Api.getFormatedPosition(value) + " Atribuição invalida. Reference ainda não aponta para uma área de memoria valida!");
- // }
- // return;
- // }
- //
- // if (!aTipo.equals(eTipo)) {
- // AddError(Api.getFormatedPosition(value) + " Atribuição invalida. Tipo esperado {"
- // + eTipo + "} enquanto o atribuido foi {" + aTipo + "}.");
- // }
- //
- // }
- //
- // //--------------------------------------------------//
- //
- //
- // //##################################################//
- // /**
- // * Verifica: <br>
- // * -> Se uma variavel foi redeclara.
- // *
- // * @param nome
- // */
- // protected boolean _$RedeclaracaoVar(String nome, Node current) throws Exception {
- // ArrayList<Node> declaracoes = current
- // .closest("atributos,dec::function,dec::thread,dec::globais,trap", "class")
- // .encontreTodos("dec::var", "class");
- //// filtrarFilhosPorClass();
- // int cId = current.GetInt("id");
- // int tId;
- // for (Node node : declaracoes) {
- // tId = node.GetInt("id");
- // if (tId >= cId) {
- // break;
- // }
- // if (node.igual("value", nome)) {
- // AddErrorWithPosition(" Redeclaração [ Variavel {" + nome
- // + "}]. Primeira definição na linha {" + node.Get("line") + "}");
- // return true;
- // }
- // }
- // return false;
- //
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Redeclaração de uma função no mesmo escopo
- // *
- // * @throws Exception
- // */
- // protected void _checkRedeclaracaoFuncao() throws Exception {
- // String nomeFuncao = current.getText();
- // ArrayList<Node> funcoes = current.parent.filtrarFilhosPorClass("dec::function");
- // int cId = current.GetInt("id");
- // int tId;
- // for (Node node : funcoes) {
- // tId = node.GetInt("id");
- // if (tId >= cId) {
- // break;
- // }
- // if (node.igual("value", nomeFuncao)) {
- // AddError(Api.getFormatedPosition(current) + "Redeclaração de função. Previa declaração na linha {" + node.Get("line") + "}");
- // return;
- // }
- // }
- // }
- //
- // protected void _verificarAtribuicaoVetor(Node variavel, Node valor) throws Exception {
- //// System.out.println("Var:" + variavel.encontre("indices"));
- //
- // String tipoEsperado = variavel.Get("tipo");
- // Node indices = variavel.encontre("indices");
- // int numeroIndices = indices.getChildrenCount();
- //
- //// System.out.println("\n\nAtribuicao:" + current);
- //// Node valor = current.getPrimeiroFilho();
- //// System.out.println("valor:" + valor);
- // if (!valor.igual("class", "lista")) {
- // String tipo = valor.Get("tipo");
- // AddErrorWithPosition("Atribuição invalida. Aguardando uma lista de "
- // + tipoEsperado + ". Um(a) {" + tipo + "} foi atribuido.");
- // return;
- // }
- //// System.out.println("Valor era matrix:" + valor.igual("matrix", "true"));
- // Node visit;
- // if (numeroIndices > 1 && !valor.igual("matrix", "true")) //Caso tenha mais de uma linha de inicializacao
- // {
- //// System.out.println("ATRIB:" + valor);
- // AddErrorWithPosition(" Numero de itens não corresponde ao esperado. Esperado {" + numeroIndices + "} atribuido {1}");
- // return;
- // }
- // if (valor.igual("matrix", "true")) {
- // visit = valor;
- // } else { //Caso seja apenas um vetor
- //// valor:[value: lista, id: 17, _pos: 0, class: lista, tipo: array, line: 14, col: 16, file: program::exemplo, ][1,3,] sem ()
- //// valor:[value: lista, id: 17, _pos: 0, class: lista, tipo: array, line: 14, col: 16, file: program::exemplo, ][lista,] ()
- //
- //// valor:[value: lista, id: 8, _pos: 0, class: lista, tipo: array, line: 14, col: 14, file: program::exemplo, ][1,2,]
- //// valor:[value: lista, id: 8, _pos: 0, class: lista, tipo: array, line: 14, col: 14, file: program::exemplo, ][lista,]
- //// System.out.println("valor:" + valor);
- // Node lista = valor.first();
- // if (lista.igual("class", "lista")) {
- // visit = lista;
- // } else {
- // visit = valor;
- // }
- // }
- // __conferirListaAtribuicao(indices, visit, 0, tipoEsperado, numeroIndices);
- // }
- //
- // protected void __conferirListaAtribuicao(Node indices, Node valor, int ind, String tipo, int numeroIndices) throws Exception {
- //// System.out.println("Valores:" + valor);
- // if (!indices.temFilho(ind)) {
- // return;
- // }
- // int numEle = indices.getFilho(ind).GetInt("value");
- // int numAtrib = valor.getChildrenCount();
- //
- // if (numeroIndices == 1) { //diz que e um vetor;
- // if (numEle != numAtrib) {
- // AddErrorWithPosition(" Numero de itens não corresponde ao esperado. Esperado {"
- // + numEle + "} atribuido {" + numAtrib + "}.");
- // }
- // checkTipo(tipo, valor.filhos(), "");
- // } else { //diz que é uma matrix
- //// System.out.println("ASDASD:" + ind + ":" + (numeroIndices - 1));
- // if (numEle != numAtrib) {
- // AddErrorWithPosition(" Numero de itens não corresponde ao esperado. Esperado {"
- // + numEle + "} atribuido {" + numAtrib + "}.");
- // return;
- // }
- // if (ind == numeroIndices - 1) {
- // checkTipo(tipo, valor.filhos(), "");
- // } else {
- // for (Node atribuicao : valor.filhos()) {
- // __conferirListaAtribuicao(indices, atribuicao, ind + 1, tipo, numeroIndices);
- // }
- // }
- // }
- // }
- //
- // protected Node getOperandoNaAst(Node n, Node parent) {
- // if (n.eNumerico("value") || n.igual("class", "valor")) {
- // return n;
- // }
- // return findVariavel(n);
- // }
- //
- // /**
- // *
- // * @param n Sera extraido a poiscao e o texto
- // * @param tipo tipo do valor atribuido
- // * @param esperado tipo do valor esperado
- // * @param op operação [atribuição,]
- // */
- // protected void tipoCheck(Node n, String tipo, String esperado, String op) {
- // if (tipo == null) {
- // tipo = "undefined";
- // }
- // String acesso = (n.temAtributo("fullAccess")) ? n.Get("fullAccess") : n.getText();
- // if (!tipo.equals(esperado)) {
- // AddError(Api.getFormatedPosition(n) + " Operação { " + op + " } espera um valor ["
- // + esperado + "]. Parametro { " + acesso + " } é do tipo [" + tipo + "]");
- // }
- // }
- //
- //
- // protected static String tipoVar(Node n) {
- // Node nv = findVariavel(n);
- // String tipo = "undefined";
- // /*Se a variavel não existir*/
- // if (null == nv) {
- // return tipo;
- // }
- //
- // Node atributo = n.encontreByClass("atributo");
- //
- // /*Se não tem atributo*/
- // if (null == atributo) {
- // return n.Get("tipo");
- // }
- //
- // /*Se tem atributo*/
- // while (null != atributo) {
- // tipo = atributo.Get("tipo");
- // atributo = atributo.encontreByClass("atributo");
- // }
- // return tipo;
- // }
- //
- // protected static Node findVariavel(Node var) {
- // return findVariavel(var, true);
- // }
- //
- //// protected Node findVariavel(Node var, Node parent, boolean AddError) {
- // protected static Node findVariavel(Node var, boolean AddError) {
- //// if (Constantes.existe(var.getText())) {
- //// return Constantes.
- //// }
- // Node dec = Variables.find(var.getText(), var.Get("escopo"));
- // if (dec == null && AddError) {
- //// System.out.println("Var:" + var);
- //// new Exception().printStackTrace();
- // AddError(Api.getFormatedPosition(var) + " Tentativa de acesso identificador {" + var.getText() + "} não declarada no escopo.");
- // }
- // return dec;
- // }
- //
- //
- //
- // /**
- // *
- // * @param n
- // * @param tipoEsperado
- // * @param onde
- // * @return true se iguais e false caso sejam diferentes
- // */
- // protected boolean checkTipo(String tipoEsperado, Node n, String onde) {
- // if (n.igual("tipo", "undefined")) {
- // switch (n.Class()) {
- // case "var":
- // n = findVariavel(n);
- //// n = ast.encontreDeclaracao(n, n.parent);
- // break;
- // case "function::call":
- // n = encontreFuncao(n.getText(), true);
- //// n = ast.encontreFuncao(n.getText());
- // break;
- // }
- // }
- //
- // if (!n.igual("tipo", tipoEsperado)) {
- // switch (onde) {
- // case "retorno":
- // AddErrorWithPosition(" Retorno invalido. Tipo esperado {" + tipoEsperado + "} enquanto o atribuido foi {" + n.Get("tipo") + "}.");
- // break;
- // default:
- // AddErrorWithPosition(" Atribuição invalida. Tipo esperado {" + tipoEsperado + "} enquanto o atribuido foi {" + n.Get("tipo") + "}.");
- // }
- // return false;
- // }
- // return true;
- // }
- //
- // protected void checkTipo(String tipoEsperado, ArrayList<Node> nodes, String onde) {
- // for (Node v : nodes) {
- // checkTipo(tipoEsperado, v, onde);
- // }
- // }
- //
- // public static boolean testExist(Node n) {
- // return testExist(n, true);
- // }
- //
- // public static boolean testExist(Node n, boolean AddError) {
- // if (n == null) {
- // return false;
- // }
- // switch (n.Get("class")) {
- //// case "function::call":
- //// Node func = encontreFuncao(n.getText(), AddError);
- //// if (func != null) {
- //// return true;
- //// }
- //// break;
- //// case "dec::var":
- //// return true;
- //// case "assign::op":
- //// n = n.first();
- //// case "var":
- //// return findVariavel(n, AddError) != null;
- ////
- //// case "const":
- //// return Constantes.existe(n.getText());
- ////
- //// case "op::unaria":
- //// case "exp::boolena":
- //// case "valor":
- //// case "exp::aritimetica":
- //// return true;
- // }
- // return false;
- // }
- //
- // protected Node program() {
- // return Root().encontre("program");
- // }
- //
- // protected boolean _$redeclaracao(String nome, String tipo, String onde, int id) throws Exception {
- // for (Node c : program().encontre(onde).filhos()) {
- // if (nome.equals(c.getText()) && id > c.GetInt("id")) {
- // AddErrorWithPosition(" Redeclaração [ " + tipo + " {" + nome + "}]. Primeira definição na linha {" + c.Get("line") + "}");
- // return true;
- // }
- // }
- // return false;
- // }
- //
- // /**
- // * Verifica: <br>
- // * -> Se a constante é duplicada existe; <br>
- // * -> Se o tipo atribuido é igual ao esperado
- // */
- // protected void chkConstante() throws Exception {
- // /*Verificar se constante foi redeclarada*/
- //
- //// if (_$redeclaracao(current.getText(), "Constante", "constantes", current.GetInt("id"))) {
- //// return;
- //// }
- // }
- ////
- // /**
- // * Verifica: <br>
- // * -> Se existe uma constante com mesmo nome <br>
- // * -> Se o tipo existe <br>
- // * -> Se ocorre redeclaração da variavel
- // *
- // * @throws Exception
- // */
- // protected void verificarDecVariavel() throws Exception {
- // String nome = current.getText();
- // if (_$RedeclaracaoVar(nome, current)) {
- // return;
- // }
- // if (Constantes.existe(nome)) {
- // AddErrorWithPosition(" Declaração invalida. Variavel {" + nome + "} com mesmo identificador de uma constante.");
- // return;
- // }
- // _testeTipoValido(current);
- // /*Se for matrix avalia os limites*/
- // if (current.igual("matrix", "true")
- // && !_$indicesValidos(current, current.encontre("indices"), false)) {
- // }
- // Node assign = current.encontreByClass("assign");
- // if (null != assign) {
- // chkAssign(assign);
- // }
- // }
- //
- // /**
- // * Verifica se o tipo existe; Adiciona mensagem de erro caso contrario;
- // *
- // * @param n
- // * @return
- // * @throws Exception
- // */
- // protected boolean _testeTipoValido(Node n) throws Exception {
- // String tipo = n.Get("tipo");
- // boolean exit = Types.existe(tipo);
- // if (!exit) {
- // AddError(Api.getFormatedPosition(n) + " Tipo invalido. Tipo {" + tipo + "} não definido.");
- // }
- // return exit;
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Função com mesmo nome de uma variavel <br>
- // * -> Se função foi redeclarada <br>
- // *
- // * @throws Exception
- // */
- // protected void verificarFuncao() throws Exception {
- //
- // String nomeFuncao = current.getText();
- // if (Variables.existe(current)) {
- // AddErrorWithPosition("Declaração invalida. Função com mesmo nome de uma variavel {" + nomeFuncao + "}.");
- // }
- // _$redeclaracao(nomeFuncao, "Funções", "funcoes", current.GetInt("id"));
- //// _checkRedeclaracaoFuncao();
- // // _checkRetornoFuncao();
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Se o retorno é o mesmo esperado pela função ;
- // */
- // protected void checkRetornoFuncao() {
- // Node parent = current.closest("dec::function,dec::thread", "class");
- // /*Se não estiver dentro de uma função ou thread*/
- // if (null == parent) {
- // return;
- // }
- // /*Se estiver dentro de uma thread não verifica*/
- // if (parent.igual("class", "dec::thread")) {
- // return;
- // }
- // String tipoEsperado = parent.Get("tipo"),
- // tipoAtribuido = tipo(current.first());
- //
- // if (!tipoAtribuido.equals(tipoEsperado) && !tipoAtribuido.equals(Types.REFERENCE)) {
- // AddErrorWithPosition(" Tipo de retorno invalido. Retornando {" + tipoAtribuido + "} enquanto o esperador é {" + tipoEsperado + "}");
- // }
- // }
- //
- //
- // /**
- // * Verifica:<br>
- // * -> Se função existe
- // */
- // protected void chkChamadaDeFuncao() {
- // if (current.in("value", new String[]{"print", "read"})) {
- // return;
- // }
- // String id = current.getText();
- //
- // if (null == encontreFuncao(id, false)) {
- // AddErrorWithPosition(" Chamada de função invalida. Não foi encontrada declaração para a função ['" + id + "'].");
- // }
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Se uma variavel existe.<br>
- // * -> Se for matrix avalia os limites
- // *
- // * @param nome
- // */
- // protected void verificarVariavel(Node var) throws Exception {
- // Node dec = findVariavel(var, true);
- // if (null == dec) {
- // var.Set("verificador", "1");
- // return;
- // }
- // if (!_$checkAtributoAndIndices(dec, var)) {
- // var.Set("verificador", "1");
- // }
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Se uma atributo existe <br>
- // * -> Se for matrix avalia os limites
- // *
- // * @throws Exception
- // */
- // protected boolean checkAtributo(Node current) throws Exception {
- // if (current == null) {
- // return false;
- // }
- //
- // String tipoParent = current.parent.Get("tipo");
- //
- // if (tipoParent.equals("undefined")) {
- // return false;
- // }
- //
- // Node pTipo = Types.Get(tipoParent);
- // String atributo = Variables.clearName(current.getText());
- // Node dec = pTipo.first().encontre(atributo);
- // /*Verifica se o atributo existe*/
- // if (null == dec) {
- // AddErrorWithPosition(" Acesso invalido de atributo. A variavel [ "
- // + current.parent.getText() + " | tipo: " + pTipo.getText()
- // + " ] não possui o atributo {" + atributo + "}");
- // return false;
- // }
- // return _$checkAtributoAndIndices(dec, current);
- // }
- //
- // /**
- // * Executa recursivamente a verificação de atributos e a verificação de
- // * indices
- // *
- // * @param dec
- // * @param current
- // * @throws Exception
- // */
- // protected boolean _$checkAtributoAndIndices(Node dec, Node current) throws Exception {
- // /*Verificar array limites*/
- // Node indices = current.encontre("indices");
- // if (null != indices && !_$indicesValidos(dec, indices, true)) {
- // current.Set("verificador", "1");
- // return false;
- // }
- // Node atributo = current.encontreByClass("atributo");
- // /*Se tem um proxumo atributo e é array*/
- // if (null != atributo && dec.igual("matrix", "true")) {
- // Node decInd = dec.encontre("indices"),
- // curInd = current.encontre("indices");
- //
- // /*Isso indica que deve estar sendo accessado um array e uma variavel*/
- // if (null == curInd || decInd.getChildrenCount() > curInd.getChildrenCount()) {
- //
- // AddErrorWithPosition(" Acesso invalido. Tentando acessar o atributo {" + atributo.getText() + "} de um array.");
- // current.Set("verificador", "1");
- // return false;
- // }
- // }
- //
- // /*Ativa recursao dos atributos*/
- // if (!checkAtributo(atributo)) {
- // current.Set("verificador", "1");
- // return false;
- // }
- // return true;
- // }
- //
- // /**
- // * Verifica:<br>
- // * -> Se os indices são do tipo inteiro <br>
- // * -> Se for valor verifica se o limite é valido
- // *
- // * @param dec
- // * @param indicesAccess
- // * @param chkLimite
- // * @throws Exception
- // */
- // protected boolean _$indicesValidos(Node dec, Node indicesAccess, boolean chkLimite) throws Exception {
- // boolean valid = true;
- // /*Caso o a variavel não seja um matriz*/
- // if (!dec.igual("matrix", "true")) {
- // AddErrorWithPosition(" Acesso invalido. Propriedade {" + dec.getText() + "} não é um vetor.");
- // return false;
- // }
- // ArrayList<Node> indices = indicesAccess.filhos();
- // ArrayList<Node> decIndices = dec.encontre("indices").filhos();
- //
- // if (indices.size() > decIndices.size()) {
- // AddErrorWithPosition(" Acesso invalido. Tentando acessar indices fora do espaço da matriz.");
- // return false;
- // }
- //
- // Node decIndice;
- // String tIndice;
- // Node indice;
- // for (int i = 0, valIndAce, valIndDec; i < indices.size(); i++) {
- // indice = indices.Get(i);
- // tIndice = tipo(indice);
- //
- // _analise(indice);
- //
- // if (tIndice.equals("undefined")) {
- // valid = false;
- // continue;
- // }
- //
- // /*Verifica se o indice é inteiro */
- // if (!tIndice.equals("int")) {
- // AddErrorWithPosition(" Indice erro. Indice [" + (i + 1) + "] deve ser inteiro, {" + tIndice + "} atribuido.");
- // valid = false;
- // continue;
- // }
- // /*Quando for uma declaração não deve conferir os limites, verificação
- // apenas deve ser feita quando se tratar de acesso a variavel*/
- //
- // /*Verificar limite apenas quando for numero inteiro*/
- // if (!chkLimite || !indice.in("class", new String[]{"valor", "indice"})) {
- // continue;
- // }
- //
- // decIndice = decIndices.Get(i);
- // if (!decIndice.in("class", new String[]{"valor", "indice"})) {
- // continue;
- // }
- //
- // /* Quantidade de indices da chamada */
- // valIndAce = indice.GetInt("value");
- // valIndDec = decIndice.GetInt("value");
- //
- // if (valIndAce >= valIndDec) {
- // AddErrorWithPosition(" Indice erro. Indice [" + (i + 1) + "], valor maximo {" + (valIndDec - 1) + "}, atribuido {" + valIndAce + "}.");
- // valid = false;
- // }
- // }
- // return valid;
- // }
- //
- // /**
- // * Registra o erro caso a quantidade de parametros seja diferente da
- // * declarada
- // *
- // * @param numParametros
- // * @param sizedec
- // */
- // protected boolean _$verificarQuantidadeParametros(int numParametros, int sizedec) {
- // if (numParametros > sizedec) {
- // AddErrorWithPosition(" Chamada invalida. Função chamada com mais "
- // + "parametros que o declarado. Esperando {"
- // + sizedec + "}, atribuidos {" + numParametros + "}");
- // return false;
- // } else if (numParametros < sizedec) {
- // AddErrorWithPosition(" Chamada invalida. Função chamada com menos "
- // + "parametros que o declarado. Esperando {"
- // + sizedec + "}, atribuidos {" + numParametros + "}");
- // return false;
- // }
- // return true;
- // }
- //
- // protected void _$verificarTipoParametro(ArrayList<Node> paramdec) {
- // Node funcao = current.parent;
- // ArrayList<Node> parampas = current.filhos();
- // int i = 0;
- // String tipoAtrib, tipoEsper;
- // try {
- // for (Node param : parampas) {
- // param = param.first();
- //
- // tipoAtrib = Types.tipoDe(param, param.Get("tipo"));
- // tipoEsper = paramdec.Get(i++).Get("tipo");
- //
- // if (tipoEsper.equals(tipoAtrib)
- // || tipoEsper.equals(Types.REFERENCE)) {
- // continue;
- // }
- //
- // AddError(Api.getFormatedPosition(funcao) + " Chamada de função {"
- // + funcao.getText() + "} invalida. Parâmetro [" + (i) + "] espera {"
- // + tipoEsper + "} não corresponde com a atribuição {"
- // + tipoAtrib + "}");
- // }
- // } catch (Exception e) {
- // System.err.println(e.getMessage());
- // e.printStackTrace();
- // }
- // }
- //
- // /**
- // * Deve ser chamada depois de analisar uma funcao ou depois da definicao de
- // * uma thread Verifica: <br>
- // * -> Se quantidade de parametros
- // */
- // protected void testarListaParametros() {
- // Node parent = current.parent;
- // ArrayList<Node> paramdec;
- // int numParametros = current.filhos().size();
- //
- // if (parent.in("class", new String[]{"print", "read"})) {
- // return;
- // }
- //
- // /*Se a lista de parametros for de uma thread*/
- // if (parent.igual("class", "dec::thread")) {
- // _$verificarQuantidadeParametros(numParametros, 1);
- // return;
- // }
- //
- // /*Se a lista de parametros for de uma função*/
- // Node declaracao = Functions.function(parent.getText());
- //
- // if (null == declaracao) {
- // return;
- // }
- // paramdec = declaracao.encontre("parametros").filhos();
- //
- // /*Verifica a quantidade de parametros é igual na chamada e na declaração*/
- // if (_$verificarQuantidadeParametros(numParametros, paramdec.size())) {
- // _$verificarTipoParametro(paramdec);
- // }
- //
- // }
- //
- // /**
- // * Verfica: <br>
- // * -> Parametros da função print,se valores e variaveis existem.
- // *
- // */
- // protected void chkPrint() {
- // for (Node var : current.first().filhos()) {
- // testExist(var.first());
- // }
- // }
- //
- // /**
- // * Verfica: <br>
- // * -> Parametros da função print,se valores e variaveis existem.
- // *
- // */
- // protected void chkRead() {
- // for (Node var : current.filhos()) {
- // if (!var.in("class", new String[]{"var"})) {
- // AddErrorWithPosition("A função read exige endereços de variaveis. Especifique uma variavel para armazenar a leitura");
- // }
- // testExist(var);
- // }
- // }
- //
- // protected void _addViolacaoDeConstante(String constante) {
- // AddErrorWithPosition(" Violação de contante. Tentativa de atualizar a constante {" + constante + "}.");
- // }
- //
- // /**
- // * Verfica: <br>
- // * -> Se a variavel existe. <br>
- // * -> Se o tipo da variavel é inteiro
- // */
- // protected void chkOperacaoUnario() {
- // /*Se tentar operação unaria com constate*/
- // if (Constantes.existe(current.getText())) {
- // _addViolacaoDeConstante(current.getText());
- // return;
- // }
- // Node var = ast.encontreDeclaracao(current, current.parent);
- // if (testExist(var, true) && !var.igual("tipo", "int")) {
- // AddError(Api.getFormatedPosition(current) + " Tipo { " + var.getText() + " | " + var.Get("tipo") + " } não permite operação unária.");
- // }
- // }
- ////
- //
- // /**
- // * Adiciona um erro a liSta de erroS SemanticoS
- // *
- // * @param erro
- // */
- // protected static void AddError(String erro) {
- // erros.add(erro);
- // }
- //
- // /**
- // * Seta a pilha do eSopo
- // *
- // * @param escopo
- // */
- // protected void setEscopo(String escopo) {
- // String ant = escopoStack.empty() ? "" : "," + escopoStack.peek();
- // escopoStack.push(escopo + ant);
- // }//
- // protected void DecConst() {
- //
- // }
- //
- // /**
- // * Verifica: <br>
- // * -> Se os operandos existem <br>
- // * -> Se tipo dos operandos sao validos <br>
- // */
- // protected boolean exprArithmetic() {
- // int i = 1;
- // String type;
- // for (Node node : current.childrens()) {
- // type = tipo(node);
- //
- // if (testExist(node, false) && (!type.equals(Types.REFERENCE) && !type.equals("int"))) {
- //
- // AddError(Api.getFormatedPosition(node) + " Tipo esperado {int}. "
- // + " Operando {" + i + "} é do tipo {" + node.getText() + " | " + type + "}");
- // return false;
- // }
- // i++;
- // }
- // return true;
- // }
- // /*Functions de apoio */
- //
- // protected String tipo(Node n) {
- // switch (n.Get("class")) {
- //
- //// return n.Get("type");
- // case "function::call":
- // Node func = encontreFuncao(n.getText(), false);
- // if (func != null) {
- // return func.Get("tipo");
- // }
- // break;
- //
- //// case "var":
- //// tipo = tipoVar(n);
- //// break;
- // case "indice":
- // case "dec::var":
- // case "const":
- // return n.Get("type");
- //
- // case "expr::or":
- // case "expr::and":
- // case "expr::comp":
- // case "value.boolean":
- // return Types.BOOLEAN;
- //
- // case "expr::unary":
- // case "expr::negative":
- // case "expr::arithmetic":
- // case "value.integer":
- // return Types.INTEGER;
- // }
- // return Types.UNDEFINED;
- // }
|