IvannosysCompiler.java 9.0 KB

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