IvannosysCompiler.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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.Instruction;
  9. import IntermediaryCode.Code;
  10. import IntermediaryCode.TacGenInterface;
  11. import ast.AbstractSyntaxTree;
  12. import ast.Semantic;
  13. import common.ErrorReport;
  14. import common.Log;
  15. import grammar.IvannosysGrammarLexer;
  16. import grammar.IvannosysGrammarParser;
  17. import grammar.visitorAndWalkers.IvannosysListener;
  18. import grammar.visitorAndWalkers.IvannosysVisitor;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.util.ArrayList;
  22. import java.util.Arrays;
  23. import java.util.HashMap;
  24. import javax.swing.JFrame;
  25. import javax.swing.JPanel;
  26. import org.antlr.v4.gui.TreeViewer;
  27. import org.antlr.v4.runtime.ANTLRFileStream;
  28. import org.antlr.v4.runtime.ANTLRInputStream;
  29. import org.antlr.v4.runtime.CommonTokenStream;
  30. import org.antlr.v4.runtime.TokenStream;
  31. import org.antlr.v4.runtime.tree.ParseTreeWalker;
  32. /**
  33. *
  34. * @author Eugenio
  35. */
  36. public class IvannosysCompiler {
  37. public static final int INPUT_FILE = 0;
  38. public static final int INPUT_STREAM = 1;
  39. protected String inputFile = "";
  40. protected String inputStream = "";
  41. protected String encType = "UTF-8";
  42. protected int inputType = 0;
  43. public ArrayList<String> path;
  44. public ArrayList<String> pathLibs;
  45. protected ParseTreeWalker walker;
  46. protected IvannosysListener listener;
  47. protected IvannosysGrammarParser.InitContext tree;
  48. // protected IvannosysVisitor iVisitor;
  49. protected HashMap<String, IvannosysTargetArch> targets = new HashMap<>();
  50. // protected HashMap<String, IvannosysVisitor> visitors;
  51. protected HashMap<String, AbstractSyntaxTree> asts;
  52. protected AbstractSyntaxTree ast;
  53. protected HashMap<String, String> settings;
  54. protected String ExtensionLibrary = ".go";
  55. protected String EnvPathVarName = "IVANPATH";
  56. protected String EnvBinVarName = "IVANBIN";
  57. protected String EnvRootVarName = "IVANROOT";
  58. protected TacGenInterface tac;
  59. IvannosysCompiler(String srcinputprogram, String enc, int inputType) throws Exception {
  60. settings = new HashMap<>();
  61. path = new ArrayList<>();
  62. pathLibs = new ArrayList<>();
  63. // visitors = new HashMap<>();
  64. asts = new HashMap<>();
  65. ast = AbstractSyntaxTree.getAbstractSyntaxTree();
  66. if (inputType == INPUT_STREAM) {
  67. inputStream = srcinputprogram;
  68. } else {
  69. inputFile = srcinputprogram;
  70. }
  71. encType = enc;
  72. inicializarSrcPath();
  73. inicializarSettings();
  74. }
  75. protected IvannosysCompiler RegisterTarget(String id, IvannosysTargetArch target) {
  76. targets.put(id, target);
  77. return this;
  78. }
  79. protected boolean HasTarget(String id) {
  80. return targets.containsKey(id);
  81. }
  82. protected void inicializarSrcPath() throws Exception {
  83. String[] variavies = new String[]{this.EnvPathVarName, this.EnvRootVarName};
  84. for (String variavel : variavies) {
  85. variavel = System.getenv(variavel);
  86. if (variavel == null) {
  87. throw new Exception(String.format("Não encontrou a variável de ambeinte %s.", variavel));
  88. }
  89. include(variavel);
  90. }
  91. }
  92. /**
  93. * StingS.put("clearCode", true);<br>
  94. * StingS.put("developement",falSe);<br>
  95. * StingS.put("diSplayASt", falSe);<br>
  96. * StingS.put("diSplayErroS", falSe);<br>
  97. * StingS.put("diSplaParSerTree", falSe);
  98. *
  99. * @return
  100. */
  101. public IvannosysCompiler inicializarSettings() {
  102. settings.put("clearCode", "true");
  103. settings.put("developement", "false");
  104. settings.put("displayAst", "false");
  105. settings.put("displayErros", "false");
  106. settings.put("displaParserTree", "false");
  107. return this;
  108. }
  109. public IvannosysCompiler setSetting(String prop, String valor) {
  110. settings.put(prop, valor);
  111. return this;
  112. }
  113. public IvannosysCompiler setLimparCodigo(String lc) {
  114. settings.put("clearCode", lc);
  115. return this;
  116. }
  117. public IvannosysListener getListener() throws Exception {
  118. if (null == listener) {
  119. listener = new IvannosysListener(this);
  120. }
  121. return listener;
  122. }
  123. public IvannosysCompiler Compile() throws IOException, Exception {
  124. try {
  125. // create a CharStream that reads from standard input
  126. ANTLRInputStream input;
  127. if (inputType == INPUT_STREAM) {
  128. input = new ANTLRInputStream(inputStream);
  129. } else {
  130. input = new ANTLRFileStream(inputFile, encType);
  131. }
  132. SyntaxError se = new SyntaxError();
  133. IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input);
  134. lexer.removeErrorListeners();
  135. lexer.addErrorListener(se);
  136. CommonTokenStream tokens = new CommonTokenStream(lexer);
  137. IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens);
  138. parser.removeErrorListeners();
  139. parser.addErrorListener(se);
  140. tree = parser.init(); // begin parsing at init rule
  141. if (se.HasError()) {
  142. abortarPorErro(se, "parser");
  143. return this;
  144. }
  145. Api.inicializar(this);
  146. listener = getListener();
  147. walker = new ParseTreeWalker();
  148. Log be = new IvannosysVisitor(tree, parser.getTokenNames(), this).Error();
  149. if (be.HasError()) {
  150. abortarPorErro(be, "visitor");
  151. return this;
  152. }
  153. /**
  154. * Etapa de geração da arvore sintatica e analise semantica
  155. */
  156. walker.walk(listener, tree);
  157. be = listener.Error();
  158. if (be.HasError()) {
  159. abortarPorErro(be, "listener");
  160. return this;
  161. }
  162. DisplayAST(parser);
  163. // Variaveis.List();
  164. Semantic semantic = new Semantic(ast);
  165. if (semantic.Execute().HasError()) {
  166. abortarPorErro(semantic, "semantic");
  167. }
  168. // Funcoes.genCallTree(ast);
  169. /**
  170. * Etapa de geração de codigo de 3 enderecos
  171. */
  172. Log.PrintInfo("TAC", new Instruction().S("msg", "Gerando código de três endereços"));
  173. Code code = tac.Create(ast, settings);
  174. // return this;
  175. for (String arch : code.ast.getCompileParams().getList("target")) {
  176. Log.PrintInfo("TAC → TARGET", new Instruction().S("msg", "Gerando código " + arch));
  177. Generate(arch, code);
  178. }
  179. } catch (Exception e) {
  180. System.out.println(e.getMessage());
  181. if (settings.get("developement").equals("true")) {
  182. e.printStackTrace();
  183. }
  184. }
  185. return this;
  186. }
  187. public void Generate(String arch, Code code) throws Exception {
  188. if (!HasTarget(arch)) {
  189. throw new Exception(String.format("Arch '%s' não definida.", arch));
  190. }
  191. this.targets.get(arch)
  192. .SetTAC(code)
  193. .Compile()
  194. .Format()
  195. .Export();
  196. }
  197. protected void DisplayAST(IvannosysGrammarParser parser) {
  198. if (settings.get("displaParserTree").equals("true")) {
  199. // ((ParserRuleContext) tree).inspect(parser);
  200. displayTree(parser);//mostra a arvore grafica
  201. System.out.println(tree.toStringTree(parser)); // print LISP-style tree
  202. }
  203. if (settings.get("displayAst").equals("true")) {
  204. System.out.println("...................................Abstract Syntax Tree");
  205. System.out.println(ast.stringfy());
  206. }
  207. }
  208. protected void displayTree(IvannosysGrammarParser parser) {
  209. JFrame frame = new JFrame("Antlr AST");
  210. JPanel panel = new JPanel();
  211. TreeViewer viewr = new TreeViewer(Arrays.asList(
  212. parser.getRuleNames()), tree);
  213. viewr.setScale(1.5);//scale a little
  214. panel.add(viewr);
  215. frame.add(panel);
  216. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  217. frame.setSize(200, 200);
  218. frame.setVisible(true);
  219. }
  220. protected void abortarPorErro(ErrorReport er, String onde) throws Exception {
  221. System.out.println("Foram encontrados erros durante a compilação[" + onde + "]:");
  222. er.PrintErros();
  223. throw new Exception("Compilação abortada");
  224. }
  225. public IvannosysCompiler LoadPackage(String alias, String path) throws IOException, Exception {
  226. // System.out.println("Carregando biblioteca ......................... " + path);
  227. // System.out.println("Load:" + alias + ":" + path);
  228. String absPath = GetFileInPath(path);
  229. if (absPath == null) {
  230. throw new Exception(String.format("O pacote '%s' não foi encontrado no path.", path));
  231. }
  232. File folder = new File(absPath);
  233. int inc = 0;
  234. for (File file : folder.listFiles()) {
  235. if (!file.isFile()) {
  236. continue;
  237. }
  238. inc++;
  239. // System.out.println("Read file " + file.getAbsolutePath());
  240. ANTLRInputStream input = new ANTLRFileStream(file.getAbsolutePath(), encType);
  241. IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input);
  242. CommonTokenStream tokens = new CommonTokenStream(lexer);
  243. IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens);
  244. IvannosysGrammarParser.InitContext ltree = parser.init(); // begin parsing at init rule
  245. if (settings.get("displaParserTree").equals("true")) {
  246. // ((ParserRuleContext) ltree).inspect(parser); //mostra a arvore grafica
  247. System.out.println(ltree.toStringTree(parser)); // print LISP-style tree
  248. displayTree(parser);//mostra a arvore grafica
  249. }
  250. walker.walk(getListener(), ltree); // walk parse tree
  251. }
  252. if (inc == 0) {
  253. throw new Exception(String.format("Diretório '%s' não possui arquivos fonte.", absPath));
  254. }
  255. return this;
  256. }
  257. public IvannosysCompiler setDisplayParserTree(boolean b) {
  258. settings.put("displaParserTree", b ? "true" : "false");
  259. return this;
  260. }
  261. public IvannosysCompiler setDisplayErros(boolean b) {
  262. settings.put("displayErros", b ? "true" : "false");
  263. return this;
  264. }
  265. public IvannosysCompiler include(String srcinput) {
  266. if (!path.contains(srcinput)) {
  267. path.add(srcinput);
  268. }
  269. return this;
  270. }
  271. public IvannosysCompiler includeLib(String srcinput) {
  272. if (!pathLibs.contains(srcinput)) {
  273. pathLibs.add(srcinput);
  274. }
  275. return this;
  276. }
  277. public String GetFileInPath(String file) {
  278. this.path.add(0, ".");
  279. for (String x : this.path) {
  280. File f = new File(x + "\\" + file);
  281. if (f.exists() && f.isDirectory()) {
  282. return f.getAbsolutePath();
  283. }
  284. }
  285. return null;
  286. }
  287. public String getExtensionLibrary() {
  288. return ExtensionLibrary;
  289. }
  290. public IvannosysCompiler setExtensionLibrary(String ExtensionLibrary) {
  291. this.ExtensionLibrary = ExtensionLibrary;
  292. return this;
  293. }
  294. public IvannosysCompiler EnvPathVar(String ivanpath) {
  295. this.EnvPathVarName = ivanpath;
  296. return this;
  297. }
  298. public IvannosysCompiler TacGen(TacGenInterface tac) {
  299. this.tac = tac;
  300. return this;
  301. }
  302. public IvannosysCompiler Simulate() {
  303. return this;
  304. }
  305. }
  306. // protected MifFactory execEtapaGeracaoMif(MipsCodeGen mc) throws Exception {
  307. // System.out.println("...................Executando Conversão para binario");
  308. // Mif mif = null;
  309. //
  310. // MifFactory mf = new MifFactory(mc);
  311. // mc.getBlocks();
  312. //// mf.criarTraps(true);
  313. // HashMap<String, ArrayList<Instruction>> blocos = mc.getBlocks();
  314. // ArrayList<Instruction> funcoes = new ArrayList<>();
  315. // for (Map.Entry<String, ArrayList<Instruction>> bloco : blocos.entrySet()) {
  316. // String nomeBloco = bloco.getKey();
  317. // ArrayList<Instruction> b = bloco.getValue();
  318. // if (nomeBloco.equals("main")) {
  319. // mf.gerarMif(b, new Mif(1024), "mifs\\main");
  320. // } else {
  321. // funcoes.addAll(b);
  322. // }
  323. // }
  324. // mf.gerarMif(funcoes, new Mif(1024), "mifs\\funcoes");
  325. // mif = mf.criarDataStream();
  326. // mif.save("mifs\\data");
  327. //
  328. // System.out.println("..................................................ok\n");
  329. // return mf;
  330. // }
  331. // protected void loadInputStream(String path) throws IOException, Exception {
  332. // System.out.println("Carregando biblioteca ......................... " + path);
  333. //
  334. // ANTLRInputStream input = new ANTLRFileStream(path, encType);
  335. // IvannosysGrammarLexer lexer = new IvannosysGrammarLexer(input);
  336. // CommonTokenStream tokens = new CommonTokenStream(lexer);
  337. // IvannosysGrammarParser parser = new IvannosysGrammarParser((TokenStream) tokens);
  338. // IvannosysGrammarParser.InitContext ltree = parser.init(); // begin parsing at init rule
  339. //
  340. // if (settings.G("displaParserTree").equals("true")) {
  341. //// ((ParserRuleContext) ltree).inspect(parser); //mostra a arvore grafica
  342. // displayTree(parser);//mostra a arvore grafica
  343. // System.out.println(ltree.toStringTree(parser)); // print LISP-style tree
  344. // }
  345. // walker.walk(getListener(), ltree); // walk parse tree
  346. // }