IvannosysCompiler.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package compiler;
  7. import API.Api;
  8. import API.BuildParams;
  9. import API.Target;
  10. import IntermediaryCode.IRGenInterface;
  11. import ast.AbstractSyntaxTree;
  12. import common.Code;
  13. import common.ErrorReport;
  14. import common.Instruction;
  15. import common.IvannosysTargetArch;
  16. import common.Log;
  17. import common.SyntaxError;
  18. import frontend.Ivannosys.IvannosysListener;
  19. import frontend.Ivannosys.IvannosysVisitor;
  20. import grammar.IvannosysGrammarLexer;
  21. import grammar.IvannosysGrammarParser;
  22. import java.io.File;
  23. import java.io.IOException;
  24. import java.util.ArrayList;
  25. import java.util.Arrays;
  26. import java.util.HashMap;
  27. import javax.swing.JFrame;
  28. import javax.swing.JPanel;
  29. import org.antlr.v4.gui.TreeViewer;
  30. import org.antlr.v4.runtime.ANTLRFileStream;
  31. import org.antlr.v4.runtime.ANTLRInputStream;
  32. import org.antlr.v4.runtime.CommonTokenStream;
  33. import org.antlr.v4.runtime.TokenStream;
  34. import org.antlr.v4.runtime.tree.ParseTreeWalker;
  35. /**
  36. *
  37. * @author Eugenio
  38. */
  39. public final class IvannosysCompiler {
  40. public static final int INPUT_FILE = 0;
  41. public static final int INPUT_STREAM = 1;
  42. protected String userInput = "";
  43. protected String encType = "UTF-8";
  44. protected int inputType = 0;
  45. public ArrayList<String> path = new ArrayList<>();
  46. protected ParseTreeWalker walker;
  47. protected IvannosysListener listener;
  48. protected IRGenInterface IR;
  49. protected AbstractSyntaxTree ast;
  50. protected String ExtensionLibrary = ".go";
  51. protected IvannosysGrammarParser.InitContext tree;
  52. protected HashMap<String, AbstractSyntaxTree> asts = new HashMap<>();
  53. protected HashMap<String, IvannosysTargetArch> targets = new HashMap<>();
  54. IvannosysCompiler(String enc, int inputType) throws Exception {
  55. ast = AbstractSyntaxTree.getAbstractSyntaxTree();
  56. encType = enc;
  57. }
  58. public IvannosysCompiler IRGenerator(IRGenInterface ir) {
  59. this.IR = ir;
  60. return this;
  61. }
  62. public IvannosysListener getListener() throws Exception {
  63. if (null == listener) {
  64. listener = new IvannosysListener(this);
  65. }
  66. return listener;
  67. }
  68. public void Compile(String input) throws Exception {
  69. this.userInput = input;
  70. Compile();
  71. }
  72. protected IvannosysCompiler Compile() throws IOException, Exception {
  73. try {
  74. // create a CharStream that reads from standard input
  75. ANTLRInputStream input;
  76. if (inputType == INPUT_STREAM) {
  77. input = new ANTLRInputStream(userInput);
  78. } else {
  79. input = new ANTLRFileStream(userInput, encType);
  80. }
  81. SyntaxError se = new SyntaxError();
  82. IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input);
  83. lexer.removeErrorListeners();
  84. lexer.addErrorListener(se);
  85. CommonTokenStream tokens = new CommonTokenStream(lexer);
  86. IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens);
  87. parser.removeErrorListeners();
  88. parser.addErrorListener(se);
  89. tree = parser.init(); // begin parsing at init rule
  90. if (se.HasError()) {
  91. abortarPorErro(se, "parser");
  92. return this;
  93. }
  94. listener = getListener();
  95. walker = new ParseTreeWalker();
  96. Log be = new IvannosysVisitor(tree, parser.getTokenNames(), this).Error();
  97. if (be.HasError()) {
  98. abortarPorErro(be, "visitor");
  99. return this;
  100. }
  101. /**
  102. * Etapa de geração da arvore sintatica e analise semantica
  103. */
  104. walker.walk(listener, tree);
  105. be = listener.Error();
  106. if (be.HasError()) {
  107. abortarPorErro(be, "listener");
  108. return this;
  109. }
  110. Api.Update();
  111. Api.List();
  112. DisplayAST(parser);
  113. // Semantic semantic = new Semantic(ast);
  114. //
  115. // if (semantic.Execute().HasError()) {
  116. // abortarPorErro(semantic, "semantic");
  117. // }
  118. // Funcoes.genCallTree(ast);
  119. /**
  120. * Etapa de geração de codigo de 3 enderecos
  121. */
  122. Log.PrintInfo("TAC", new Instruction().Set("msg", "Gerando código de três endereços"));
  123. Code code = IR.Create(ast);
  124. for (String arch : BuildParams.Get("target")) {
  125. Log.PrintInfo("TAC → TARGET", new Instruction().Set("msg", "Gerando código " + arch));
  126. Generate(arch, code);
  127. }
  128. } catch (Exception e) {
  129. System.out.println(e.getMessage());
  130. if (BuildParams.GetFirst("mode").equals("developement")) {
  131. e.printStackTrace();
  132. }
  133. }
  134. return this;
  135. }
  136. public void Generate(String arch, Code code) throws Exception {
  137. Target.Get(arch)
  138. .SetTAC(code)
  139. .Compile()
  140. .Format()
  141. .Export();
  142. }
  143. protected void DisplayAST(IvannosysGrammarParser parser) throws Exception {
  144. if (BuildParams.GetFirst("display.PARSETREE").equals("true")) {
  145. // ((ParserRuleContext) tree).inspect(parser);
  146. displayTree(parser);//mostra a arvore grafica
  147. System.out.println(tree.toStringTree(parser)); // print LISP-style tree
  148. }
  149. if (BuildParams.GetFirst("display.AST").equals("true")) {
  150. System.out.println("...................................Abstract Syntax Tree");
  151. System.out.println(ast.stringfy());
  152. }
  153. }
  154. protected void displayTree(IvannosysGrammarParser parser) {
  155. JFrame frame = new JFrame("Antlr AST");
  156. JPanel panel = new JPanel();
  157. TreeViewer viewr = new TreeViewer(Arrays.asList(
  158. parser.getRuleNames()), tree);
  159. viewr.setScale(1.5);//scale a little
  160. panel.add(viewr);
  161. frame.add(panel);
  162. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  163. frame.setSize(200, 200);
  164. frame.setVisible(true);
  165. }
  166. protected void abortarPorErro(ErrorReport er, String onde) throws Exception {
  167. System.out.println("Foram encontrados erros durante a compilação[" + onde + "]:");
  168. er.PrintErros();
  169. throw new Exception("Compilação abortada");
  170. }
  171. public IvannosysCompiler LoadPackage(String alias, String path) throws IOException, Exception {
  172. // System.out.println("Carregando biblioteca ......................... " + path);
  173. // System.out.println("Load:" + alias + ":" + path);
  174. String absPath = GetFileInPath(path);
  175. if (absPath == null) {
  176. throw new Exception(String.format("O pacote '%s' não foi encontrado no path.", path));
  177. }
  178. File folder = new File(absPath);
  179. int inc = 0;
  180. for (File file : folder.listFiles()) {
  181. if (!file.isFile()) {
  182. continue;
  183. }
  184. inc++;
  185. // System.out.println("Read file " + file.getAbsolutePath());
  186. ANTLRInputStream input = new ANTLRFileStream(file.getAbsolutePath(), encType);
  187. IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input);
  188. CommonTokenStream tokens = new CommonTokenStream(lexer);
  189. IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens);
  190. IvannosysGrammarParser.InitContext ltree = parser.init(); // begin parsing at init rule
  191. // if (BuildParams.GetFirst("displaParserTree").equals("true")) {
  192. //// ((ParserRuleContext) ltree).inspect(parser); //mostra a arvore grafica
  193. // System.out.println(ltree.toStringTree(parser)); // print LISP-style tree
  194. // displayTree(parser);//mostra a arvore grafica
  195. // }
  196. walker.walk(getListener(), ltree); // walk parse tree
  197. }
  198. if (inc == 0) {
  199. throw new Exception(String.format("Diretório '%s' não possui arquivos fonte.", absPath));
  200. }
  201. return this;
  202. }
  203. public IvannosysCompiler include(String srcinput) {
  204. if (!path.contains(srcinput)) {
  205. path.add(srcinput);
  206. }
  207. return this;
  208. }
  209. public String GetFileInPath(String file) {
  210. this.path.add(0, ".");
  211. for (String x : this.path) {
  212. File f = new File(x + "\\" + file);
  213. if (f.exists() && f.isDirectory()) {
  214. return f.getAbsolutePath();
  215. }
  216. }
  217. return null;
  218. }
  219. public String getExtensionLibrary() {
  220. return ExtensionLibrary;
  221. }
  222. public IvannosysCompiler setExtensionLibrary(String ExtensionLibrary) {
  223. this.ExtensionLibrary = ExtensionLibrary;
  224. return this;
  225. }
  226. }