Guest User

Untitled

a guest
May 24th, 2019
113
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //@author: herykgasparini
  2. grammar Sauro;
  3.  
  4. /*---------------- PARSER INTERNALS ----------------*/
  5.  
  6. @parser::header
  7. {
  8. import java.util.ArrayList;
  9. }
  10.  
  11. @lexer::members
  12. {
  13. private DenterHelper denter = new DenterHelper(NL, SauroParser.INDENT, SauroParser.DEDENT) {
  14. @Override
  15. public Token pullToken() {
  16. return SauroLexer.super.nextToken();
  17. }
  18. };
  19.  
  20. @Override
  21. public Token nextToken() {
  22. return denter.nextToken();
  23. }
  24. }
  25.  
  26. @parser::members
  27. {
  28. private static int stack_cur, stack_max, if_counter, while_counter, list_counter;
  29.  
  30. private static void emit(String bytecode, int delta)
  31. {
  32. stack_cur += delta;
  33. System.out.println(" " + bytecode + " ; " + delta);
  34.  
  35. if (stack_cur > stack_max)
  36. {
  37. stack_max = stack_cur;
  38. }
  39. }
  40.  
  41. private static ArrayList<String> symbol_table;
  42. private static int errors;
  43. private static ArrayList<String> symbol_table_use;
  44. private static ArrayList<String> symbol_table_type;
  45.  
  46. public static void main(String[] args) throws Exception
  47. {
  48. CharStream input = CharStreams.fromStream(System.in);
  49. //recebe do terminal
  50. SauroLexer lexer = new SauroLexer(input);
  51. //Lexer lê a entrada e gera sequencia de Tokens
  52. CommonTokenStream tokens = new CommonTokenStream(lexer);
  53. SauroParser parser = new SauroParser(tokens);
  54.  
  55. symbol_table = new ArrayList<String>();
  56. symbol_table_type = new ArrayList<String>();
  57. symbol_table_use = new ArrayList<String>();
  58. symbol_table.add("args");
  59. errors = 0;
  60. symbol_table_type.add("-");
  61.  
  62. parser.program(); //aqui começa nosso programa, ele é chamado
  63.  
  64. System.out.println("; symbols: " + symbol_table); // o ; é um comentário do .j
  65. //symbol table é nossa tabela de índices X variáveis... args tem índice 0 já. índice é nosso endereço de memória, 0, 1, 2, ... Faz istore 1, 2, 3
  66.  
  67. System.out.println("; symbols not used: " + symbol_table_use);
  68.  
  69. if(errors > 0 )
  70. {
  71. System.err.println(errors + " error(s) occurred");
  72. System.exit(1);
  73. }
  74. }
  75. }
  76.  
  77. /*---------------- LEXER RULES ----------------*/
  78.  
  79. tokens {INDENT, DEDENT}
  80.  
  81. PLUS : '+' ;
  82. MINUS : '-' ;
  83. TIMES : '*' ;
  84. OVER : '/' ;
  85. REMAINDER : '%' ;
  86. OP_PAR : '(' ;
  87. CL_PAR : ')' ;
  88. ATTRIB : '=' ;
  89. COMMA : ',' ;
  90. OP_CUR : '{' ;
  91. CL_CUR : '}' ;
  92. EQ : '==' ;
  93. NE : '!=' ;
  94. GT : '>' ;
  95. GE : '>=' ;
  96. LT : '<' ;
  97. LE : '<=' ;
  98. DOT : '.' ;
  99. COLON : ':' ;
  100. OP_BRA : '[' ;
  101. CL_BRA : ']' ;
  102.  
  103. PRINT : 'print' ;
  104. READ_INT : 'read_int';
  105. READ_STR : 'read_str';
  106. WHILE : 'while';
  107. IF : 'if';
  108. APPEND : 'append';
  109. LIST : 'list';
  110. LEN : 'len';
  111. STR : 'str';
  112.  
  113. STRING : '"'~["]* '"';
  114. NUMBER : '0'..'9'+ ;
  115. VAR : 'a'..'z'+ ;
  116.  
  117. // SPACE : (' '|'\t'|'\r'|'\n')+ { skip(); } ;
  118. NL: ('\r'? '\n' ' '*) ;
  119.  
  120. SPACE : (' '|'\t')+ { skip(); } ;
  121.  
  122. COMMENT : '#' ~[\r\n]* { skip(); } ; //tudo que não for quebra de linha: [\r\n]
  123.  
  124. /*---------------- PARSER RULES ----------------*/
  125. //vai pro program, tem que achar o main
  126. program
  127. : {
  128. System.out.println(".source Test.j");
  129. System.out.println(".class public Test");
  130. System.out.println(".super java/lang/Object");
  131. System.out.println(" ");
  132. System.out.println(".method public <init>()V");
  133. System.out.println(" aload_0");
  134. System.out.println(" invokenonvirtual java/lang/Object/<init>()V");
  135. System.out.println(" return");
  136. System.out.println(".end method");
  137. System.out.println(" ");
  138. } main
  139. ;
  140. //vai pro main, tem que achar um statement
  141. main
  142. : {
  143. System.out.println(".method public static main([Ljava/lang/String;)V");
  144. System.out.println(" ");
  145. }
  146. ( statement )+
  147. {
  148.  
  149. System.out.println(" ");
  150. System.out.println(" return");
  151. System.out.println(" ");
  152. System.out.println(".limit locals " + symbol_table.size()); //declara que há uma variável local(2 pelo fator estatístico de correção)
  153. System.out.println(".limit stack " + stack_max);
  154. System.out.println(".end method");
  155. }
  156. ;
  157.  
  158. statement
  159. : st_print | st_attrib | st_new_list | st_list_append | st_list_attrib | st_if | st_while | NL
  160. ;
  161.  
  162. st_print
  163. : {
  164. emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  165. }
  166. PRINT OP_PAR expression
  167. {
  168. if($expression.type == 'i')
  169. {
  170. emit("invokevirtual java/io/PrintStream/print(I)V\n", -2);
  171. }
  172. else if ($expression.type == 'a')
  173. {
  174. emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
  175. }
  176.  
  177.  
  178. }
  179. ( COMMA
  180. {
  181. emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  182. emit("ldc \" \"", 1);
  183. emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
  184. emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  185. }
  186. expression
  187. {
  188. if($expression.type == 'i')
  189. {
  190. emit("invokevirtual java/io/PrintStream/print(I)V\n", -2);
  191. }
  192. else if ($expression.type == 'a')
  193. {
  194. emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
  195. }
  196. }
  197. )* CL_PAR
  198. {
  199. emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  200. emit("invokevirtual java/io/PrintStream/println()V\n", -1);
  201. }
  202. ;
  203.  
  204. //istore pega valor e salva no endereço de memória
  205. st_attrib
  206. : VAR ATTRIB expression
  207. {
  208. //$VAR.text é como sabemos o nome da variável
  209. if(!symbol_table.contains($VAR.text))
  210. {
  211. symbol_table.add($VAR.text);
  212. symbol_table_use.add($VAR.text);
  213. if($expression.type == 'i')
  214. {
  215. symbol_table_type.add("i");
  216. } else
  217. {
  218. symbol_table_type.add("a");
  219. }
  220. } else {
  221. if( ! symbol_table_type.get(symbol_table.indexOf($VAR.text)).equalsIgnoreCase($expression.type+"") ) {
  222.  
  223. String type = "";
  224. if($expression.type != 'a') {
  225. type = "string";
  226. }
  227. else
  228. {
  229. type = "integer";
  230. }
  231. System.err.println("#error line '" + $VAR.line + "': variable '" + $VAR.text + "' is "+ type);
  232. errors++;
  233. }
  234. }
  235.  
  236. emit( $expression.type + "store " + symbol_table.indexOf($VAR.text) + "\n", -1);
  237. }
  238. ;
  239.  
  240. st_new_list
  241. :
  242. VAR ATTRIB LIST OP_PAR CL_PAR
  243. {
  244. //$VAR.text é como sabemos o nome da variável
  245. if(!symbol_table.contains($VAR.text))
  246. {
  247. symbol_table.add($VAR.text);
  248. symbol_table_use.add($VAR.text);
  249. symbol_table_type.add("l");
  250. }
  251. else
  252. {
  253.  
  254. }
  255. emit("new List",1);
  256. emit("dup",1);
  257. emit("invokespecial List/<init>()V",-1);
  258. emit("astore " + symbol_table.indexOf($VAR.text) + "\n ", -1);
  259. }
  260. ;
  261.  
  262. st_list_append
  263. :
  264. VAR DOT APPEND OP_PAR
  265. {
  266. emit("aload " + symbol_table.indexOf($VAR.text), 1);
  267. }
  268. expression
  269.  
  270. {
  271. emit("invokevirtual List/append(I)V\n", -2);
  272. }
  273. CL_PAR
  274. ;
  275.  
  276. st_list_attrib
  277. :
  278. VAR OP_BRA
  279.  
  280. { emit("aload " + symbol_table.indexOf($VAR.text), 1); }
  281.  
  282. expression CL_BRA ATTRIB expression
  283.  
  284. { emit("invokevirtual List/set(II)V\n", -3); }
  285. ;
  286.  
  287. st_if
  288. : { int if_local = ++if_counter; }
  289. IF comparison
  290. { emit("NOT_IF_"+ if_counter, -2);}
  291. COLON INDENT ( statement ) + DEDENT
  292. { System.out.println("NOT_IF_" + if_local + ":"); }
  293. ;
  294.  
  295. st_while
  296. :
  297. { int while_local = ++while_counter; }
  298. { emit("BEGIN_WHILE_"+ while_local +" :",0); }
  299. WHILE comparison
  300. { emit("END_WHILE_"+while_counter, -2); }
  301. COLON INDENT ( statement ) +
  302. { emit("goto BEGIN_WHILE_" + while_local, 0); }
  303. DEDENT
  304. { System.out.println(";dedent"); }
  305. { emit("END_WHILE_" + while_local + ":",0); }
  306. ;
  307.  
  308. comparison
  309. : e = expression op = (EQ | NE | GT | GE | LT | LE ) e2 = expression
  310. {
  311. if($e.type != $e2.type)
  312. {
  313. System.err.println("#error line '" + $op.line + "': cannot mix types:");
  314. errors++;
  315. }
  316.  
  317. if ($op.type == EQ) { System.out.print("if_"+$e.type+"cmpne "); }
  318. else if ($op.type == NE) { System.out.print("if_"+$e.type+"cmpeq "); }
  319. else if ($op.type == GT) { System.out.print("if_"+$e.type+"cmple "); }
  320. else if ($op.type == GE) { System.out.print("if_"+$e.type+"cmplt "); }
  321. else if ($op.type == LT) { System.out.print("if_"+$e.type+"cmpge "); }
  322. else if ($op.type == LE) { System.out.print("if_"+$e.type+"cmpgt "); }
  323. }
  324. ;
  325.  
  326. //Token é maiúsculo e expression minúsculo
  327. //* quer dizer que ocorre 0 ou mais daquela parte, é opcional
  328. expression returns [char type]
  329. : t1 = term ( op = ( PLUS | MINUS ) t2 = term
  330. {
  331. if($t1.type == 'a' || $t2.type == 'a')
  332. {
  333. System.err.println("#error line '" + $op.line + "': cannot mix types:");
  334. errors++;
  335. }
  336.  
  337. if ($op.type == PLUS) { emit("iadd", -1); } else { emit("isub", -1); };
  338. }
  339. )*
  340. {$type = $t1.type;}
  341. ;
  342.  
  343. term returns [char type]
  344. : f1 = factor ( op = ( TIMES | OVER | REMAINDER ) f2 = factor
  345. {
  346.  
  347. if($f1.type == 'a' || $f2.type == 'a')
  348. {
  349. System.err.println("#error line '" + $op.line + "': cannot mix types:");
  350. errors++;
  351. }
  352.  
  353.  
  354. if ($op.type == TIMES) { emit("imul", -1); }
  355. else if ($op.type == OVER) { emit("idiv", -1); }
  356. else { emit("irem", -1); }
  357. }
  358. )*
  359. {$type = $f1.type;}
  360. ;
  361.  
  362. factor returns [char type]
  363. : NUMBER
  364. {
  365. $type = 'i' ;
  366. emit("ldc "+ $NUMBER.text, 1);
  367. }
  368. | OP_PAR e = expression CL_PAR
  369. {
  370. $type = $e.type ;
  371. }
  372. | VAR
  373. OP_BRA
  374.  
  375. { emit("aload " + symbol_table.indexOf($VAR.text) , 1); }
  376.  
  377. e = expression
  378.  
  379. CL_BRA
  380. {
  381. if(symbol_table.contains($VAR.text))
  382. {
  383.  
  384. int indexOf = symbol_table.indexOf($VAR.text);
  385.  
  386. if(symbol_table_type.get(indexOf).equalsIgnoreCase("l"))
  387. {
  388.  
  389. $type = 'i';
  390.  
  391. emit("invokevirtual List/get(I)I",-1);
  392. symbol_table_use.remove($VAR.text);
  393. }
  394. }
  395. else
  396. {
  397. System.err.println("#error line '" + $VAR.line + "': variable not declared :'" + $VAR.text + "'");
  398. errors++;
  399. }
  400. }
  401.  
  402. | VAR
  403. {
  404. if(symbol_table.contains($VAR.text))
  405. {
  406.  
  407. int indexOf = symbol_table.indexOf($VAR.text);
  408.  
  409. if(symbol_table_type.get(indexOf).equalsIgnoreCase("i"))
  410. {
  411. $type = 'i';
  412. emit("iload " + indexOf, 1);
  413. symbol_table_use.remove($VAR.text);
  414. }
  415. else
  416. {
  417. $type = 'a';
  418. emit("aload " + indexOf, 1);
  419. symbol_table_use.remove($VAR.text);
  420. }
  421. }
  422. else
  423. {
  424. System.err.println("#error line '" + $VAR.line + "': variable not declared :'" + $VAR.text + "'");
  425. errors++;
  426. }
  427. }
  428.  
  429.  
  430. | READ_INT OP_PAR CL_PAR
  431. {
  432. $type = 'i' ;
  433. emit("invokestatic Runtime/readInt()I", 1);
  434. }
  435. | STRING
  436. {
  437. $type = 'a' ;
  438. emit("ldc "+ $STRING.text, 1);
  439. }
  440. | READ_STR OP_PAR CL_PAR
  441. {
  442. $type = 'a' ;
  443. emit("invokestatic Runtime/readString()Ljava/lang/String;", 1);
  444. }
  445. | LEN OP_PAR VAR CL_PAR
  446. {
  447. $type = 'i';
  448. emit("aload " + symbol_table.indexOf($VAR.text), 1);
  449. emit("invokevirtual List/len()I", 0);
  450. }
  451.  
  452. | STR OP_PAR VAR CL_PAR
  453. {
  454. $type = 'a';
  455. emit("aload " + symbol_table.indexOf($VAR.text), 1);
  456. emit("invokevirtual List/str()Ljava/lang/String;", 0);
  457. }
  458. ;
RAW Paste Data