/* * 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 compiler; import API.Api; import API.BuildParams; import API.Target; import IntermediaryCode.IRGenInterface; import ast.AbstractSyntaxTree; import common.Code; import common.ErrorReport; import common.Instruction; import common.IvannosysTargetArch; import common.Log; import common.SyntaxError; import frontend.Ivannosys.IvannosysListener; import frontend.Ivannosys.IvannosysVisitor; import grammar.IvannosysGrammarLexer; import grammar.IvannosysGrammarParser; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import javax.swing.JFrame; import javax.swing.JPanel; import org.antlr.v4.gui.TreeViewer; import org.antlr.v4.runtime.ANTLRFileStream; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.TokenStream; import org.antlr.v4.runtime.tree.ParseTreeWalker; /** * * @author Eugenio */ public final class IvannosysCompiler { public static final int INPUT_FILE = 0; public static final int INPUT_STREAM = 1; protected String userInput = ""; protected String encType = "UTF-8"; protected int inputType = 0; public ArrayList path = new ArrayList<>(); protected ParseTreeWalker walker; protected IvannosysListener listener; protected IRGenInterface IR; protected AbstractSyntaxTree ast; protected String ExtensionLibrary = ".go"; protected IvannosysGrammarParser.InitContext tree; protected HashMap asts = new HashMap<>(); protected HashMap targets = new HashMap<>(); IvannosysCompiler(String enc, int inputType) throws Exception { ast = AbstractSyntaxTree.getAbstractSyntaxTree(); encType = enc; } public IvannosysCompiler IRGenerator(IRGenInterface ir) { this.IR = ir; return this; } public IvannosysListener getListener() throws Exception { if (null == listener) { listener = new IvannosysListener(this); } return listener; } public void Compile(String input) throws Exception { this.userInput = input; Compile(); } protected IvannosysCompiler Compile() throws IOException, Exception { try { // create a CharStream that reads from standard input ANTLRInputStream input; if (inputType == INPUT_STREAM) { input = new ANTLRInputStream(userInput); } else { input = new ANTLRFileStream(userInput, encType); } SyntaxError se = new SyntaxError(); IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input); lexer.removeErrorListeners(); lexer.addErrorListener(se); CommonTokenStream tokens = new CommonTokenStream(lexer); IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens); parser.removeErrorListeners(); parser.addErrorListener(se); tree = parser.init(); // begin parsing at init rule if (se.HasError()) { abortarPorErro(se, "parser"); return this; } listener = getListener(); walker = new ParseTreeWalker(); Log be = new IvannosysVisitor(tree, parser.getTokenNames(), this).Error(); if (be.HasError()) { abortarPorErro(be, "visitor"); return this; } /** * Etapa de geração da arvore sintatica e analise semantica */ walker.walk(listener, tree); be = listener.Error(); if (be.HasError()) { abortarPorErro(be, "listener"); return this; } Api.Update(); Api.List(); DisplayAST(parser); // Semantic semantic = new Semantic(ast); // // if (semantic.Execute().HasError()) { // abortarPorErro(semantic, "semantic"); // } // Funcoes.genCallTree(ast); /** * Etapa de geração de codigo de 3 enderecos */ Log.PrintInfo("TAC", new Instruction().Set("msg", "Gerando código de três endereços")); Code code = IR.Create(ast); for (String arch : BuildParams.Get("target")) { Log.PrintInfo("TAC → TARGET", new Instruction().Set("msg", "Gerando código " + arch)); Generate(arch, code); } } catch (Exception e) { System.out.println(e.getMessage()); if (BuildParams.GetFirst("mode").equals("developement")) { e.printStackTrace(); } } return this; } public void Generate(String arch, Code code) throws Exception { Target.Get(arch) .SetTAC(code) .Compile() .Format() .Export(); } protected void DisplayAST(IvannosysGrammarParser parser) throws Exception { if (BuildParams.GetFirst("display.PARSETREE").equals("true")) { // ((ParserRuleContext) tree).inspect(parser); displayTree(parser);//mostra a arvore grafica System.out.println(tree.toStringTree(parser)); // print LISP-style tree } if (BuildParams.GetFirst("display.AST").equals("true")) { System.out.println("...................................Abstract Syntax Tree"); System.out.println(ast.stringfy()); } } protected void displayTree(IvannosysGrammarParser parser) { JFrame frame = new JFrame("Antlr AST"); JPanel panel = new JPanel(); TreeViewer viewr = new TreeViewer(Arrays.asList( parser.getRuleNames()), tree); viewr.setScale(1.5);//scale a little panel.add(viewr); frame.add(panel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.setVisible(true); } protected void abortarPorErro(ErrorReport er, String onde) throws Exception { System.out.println("Foram encontrados erros durante a compilação[" + onde + "]:"); er.PrintErros(); throw new Exception("Compilação abortada"); } public IvannosysCompiler LoadPackage(String alias, String path) throws IOException, Exception { // System.out.println("Carregando biblioteca ......................... " + path); // System.out.println("Load:" + alias + ":" + path); String absPath = GetFileInPath(path); if (absPath == null) { throw new Exception(String.format("O pacote '%s' não foi encontrado no path.", path)); } File folder = new File(absPath); int inc = 0; for (File file : folder.listFiles()) { if (!file.isFile()) { continue; } inc++; // System.out.println("Read file " + file.getAbsolutePath()); ANTLRInputStream input = new ANTLRFileStream(file.getAbsolutePath(), encType); IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens); IvannosysGrammarParser.InitContext ltree = parser.init(); // begin parsing at init rule // if (BuildParams.GetFirst("displaParserTree").equals("true")) { //// ((ParserRuleContext) ltree).inspect(parser); //mostra a arvore grafica // System.out.println(ltree.toStringTree(parser)); // print LISP-style tree // displayTree(parser);//mostra a arvore grafica // } walker.walk(getListener(), ltree); // walk parse tree } if (inc == 0) { throw new Exception(String.format("Diretório '%s' não possui arquivos fonte.", absPath)); } return this; } public IvannosysCompiler include(String srcinput) { if (!path.contains(srcinput)) { path.add(srcinput); } return this; } public String GetFileInPath(String file) { this.path.add(0, "."); for (String x : this.path) { File f = new File(x + "\\" + file); if (f.exists() && f.isDirectory()) { return f.getAbsolutePath(); } } return null; } public String getExtensionLibrary() { return ExtensionLibrary; } public IvannosysCompiler setExtensionLibrary(String ExtensionLibrary) { this.ExtensionLibrary = ExtensionLibrary; return this; } }