/* * 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.Utils; import java.util.ArrayList; import java.util.HashMap; import java.util.Stack; /** * @author Eugenio */ public final class AbstractSyntaxTree { protected int count; protected Node current; protected Node root; protected Node compileParams; protected HashMap> ganchos; protected Stack ctxs = new Stack<>(); protected static AbstractSyntaxTree instance; public AbstractSyntaxTree() { this.root = new Node("init"); Current(root); compileParams = new Node(""); // this.current = this.root; // ganchos = new HashMap<>(); // ganchos.put("constantes", new ArrayList<>()); // ganchos.put("variaveis", new ArrayList<>()); // ganchos.put("funcoes", new ArrayList<>()); // ganchos.put("threads", new ArrayList<>()); // ganchos.put("traps", new ArrayList<>()); } public Node getCompileParams() { return compileParams; } public void setCompileParams(Node compileParams) { this.compileParams = compileParams; } public static AbstractSyntaxTree getAbstractSyntaxTree() { if (instance == null) { instance = new AbstractSyntaxTree(); } return instance; } public Node setNode(Node n) { addChildren(n); this.current = n; return this.current; } public Node Current(Node n) { ctxs.push(this.current); this.current = n; return this.current; } public Node Back() { this.current = ctxs.pop(); return this.current; } public Node getTipoDefinicao(String tipo) { Node types = this.root.find("program").find("types"); Node t = null; if (types != null) { t = types.find(tipo); if (t != null) { return t; } ArrayList librarys = this.root.encontrePrimeiroGrau("library", "class"); for (Node library : librarys) { types = library.find("types"); if (types == null) { continue; } t = types.find(tipo); if (t != null) { return t; } } } return t; } public Node addChildren(Node n) { return this.current.addFilho(n); } public Node setParentToCurrent() { if (this.current.parent != null) { this.current = this.current.parent; } return this.current; } public String visit() { return root.visit(); } public String stringfy() { return root.stringfy(); } public void setAtributo(String atrib, String valor) { this.current.Set(atrib, valor); } public String getAtributo(String atrib) { return this.current.Get(atrib); } public Node getCurrent() { return this.current; } protected Node encontreFuncao(String nome) { // System.out.println("this.root" + this.root); Node ret = null; for (Node node : this.root.childrens()) { Node funcoes = node.find("funcoes"); if (funcoes == null) { continue; } for (Node func : funcoes.childrens()) { if (!func.getText().equals(nome)) { continue; } ret = func; } } return ret; } public Node getMain() { return this.root.find("main").find("main"); } protected Node encontrarDeclaracaoNaFuncao(Node var, Node parent) { Node funcao = parent.closest("dec::function", "class"); Node parametros = funcao.find("parametros"); String nome = Utils.clearName(var.getText()); if (parametros != null) { for (Node p : parametros.childrens()) { if (p.getText().equals(nome)) { return p; } } } return null; // return encontreDeclaracao(var, parent.parent); } protected Node encontrarDeclaracaoNoFor(Node var, Node parent) { Node _for = parent.closest("for", "class"); String nome = Utils.clearName(var.getText()); if (_for != null) { for (Node ini : _for.find("inicializacoes").childrens()) { // System.out.println("CLASS:" + ini.Class()); if (ini.getText().equals(nome) && ini.eq("class", "dec::var")) { return ini; } } } // System.out.println("Procurando no for e nao encontrei agora vou buscar[" + var.getText() + "] em " + parent.parent); Node val = encontreDeclaracao(var, parent.parent); // System.out.println("Retorno da busca no parent:" + val); return val; } public Node encontreDeclaracao(Node n, Node parent) { // System.out.println("Node:" + n + "\n|parent:" + parent); String nodeClass = n.Class(); /*Se for a declaracao da variavel*/ if (nodeClass.equals("dec::var")) { return n; } /*Se nao for uma variavel, atribuicao ou operacao unaria return null*/ if (!n.in("class", new String[]{"var", "assign::op", "op::unaria", "atributo"})) { return null; } String nome = Utils.clearName(n.getText()); // System.out.println("Nome1:" + nome); if (nome.contains(".")) { String[] partes = nome.split("\\."); nome = partes[0]; } // System.out.println("Nome2:" + nome); String local = "declaracao"; if (n.eq("declaracao", "library")) { local = "escopo"; } String[] escopo = n.Get(local).split("\\."); Node decNode = null; if (parent.eq("class", "dec::function") && escopo[0].equals("function")) { decNode = encontrarDeclaracaoNaFuncao(n, parent); } else if (parent.eq("class", "for")) { decNode = encontrarDeclaracaoNoFor(n, parent); } else if (parent.eq("class", "bloco")) { /*procurar no bloco*/ ArrayList declaracoes = parent.filtrarFilhosPorClass("dec::var"); for (Node node : declaracoes) { if (Utils.clearName(node.getText()).equals(nome)) { decNode = node; break; } } } if (decNode != null) { return decNode; } else if (parent.parent != null && !parent.parent.eq("value", "init")) { // System.out.println("Buscando no parent:" + n.getText() + ":" + parent.parent.Get("id")); return encontreDeclaracao(n, parent.parent); } else { // System.out.println("parent.parent:" + parent.parent); Node programa = parent.parent.find("program"); Node var = _buscar(programa, nome, "variaveis"); if (var == null) { ArrayList librarys = parent.parent.filtrarFilhosPorClass("library"); // System.out.println("librarys:" + librarys); for (Node library : librarys) { var = _buscar(library, nome, "variaveis"); if (var != null) { // System.out.println("Encontrei mat"); break; } } } return var; } } protected Node _buscar(Node root, String nome, String quem) { Node n = root.find(quem); // System.out.println("Buscando [" + nome + "]" + n); if (n != null) { ArrayList variaveis = n.childrens(); for (Node node : variaveis) { if (Utils.clearName(node.getText()).equals(nome)) { return node; } } } return null; } public Node getVariaveis() { return root.find("program").find("variaveis"); } public Node getRoot() { return root; } public ArrayList getVariaveisGlobais() { return this.getRoot().findAll("dec::globais", "class"); } public Node getPackage(String packageName) { // System.out.println("Getpackage:" + packageName + getRoot()); return getRoot().find(packageName); } public Node BuildParams() { return this.compileParams; } }