canezzy

Untitled

May 27th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.03 KB | None | 0 0
  1. %{
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "defs.h"
  5. #include "symtab.h"
  6. #include "codegen.h"
  7.  
  8. int yyparse(void);
  9. int yylex(void);
  10. int yyerror(char *s);
  11. void warning(char *s);
  12.  
  13. extern int yylineno;
  14. int out_lin = 0;
  15. char char_buffer[CHAR_BUFFER_LENGTH];
  16. int error_count = 0;
  17. int warning_count = 0;
  18. int var_num = 0;
  19. int fun_idx = -1;
  20. int fcall_idx = -1;
  21. int lab_num = -1;
  22. int inc_list[100];
  23. int trenutni_inc = 0;
  24. FILE *output;
  25. %}
  26.  
  27. %union {
  28. int i;
  29. char *s;
  30. }
  31.  
  32. %token <i> _TYPE
  33. %token _IF
  34. %token _ELSE
  35. %token _RETURN
  36. %token <s> _ID
  37. %token <s> _INT_NUMBER
  38. %token <s> _UINT_NUMBER
  39. %token _LPAREN
  40. %token _RPAREN
  41. %token _LBRACKET
  42. %token _RBRACKET
  43. %token _ASSIGN
  44. %token _SEMICOLON
  45. %token <i> _AROP
  46. %token <i> _RELOP
  47. %token _INC
  48.  
  49. %type <i> num_exp exp literal num_exp_f
  50. %type <i> function_call argument rel_exp if_part
  51.  
  52. %nonassoc ONLY_IF
  53. %nonassoc _ELSE
  54.  
  55. %%
  56.  
  57.  
  58. program
  59. : gvariable_list function_list
  60. {
  61. int idx = lookup_symbol("main", FUN);
  62. if(idx == NO_INDEX)
  63. err("undefined reference to 'main'");
  64. else
  65. if(get_type(idx) != INT)
  66. warn("return type of 'main' is not int");
  67. }
  68. ;
  69.  
  70. function_list
  71. : function
  72. | function_list function
  73. ;
  74.  
  75. function
  76. : _TYPE _ID
  77. {
  78. fun_idx = lookup_symbol($2, FUN);
  79. if(fun_idx == NO_INDEX)
  80. fun_idx = insert_symbol($2, FUN, $1, NO_ATR, NO_ATR);
  81. else
  82. err("redefinition of function '%s'", $2);
  83.  
  84. code("\n%s:", $2);
  85. code("\n\t\tPUSH\t%%14");
  86. code("\n\t\tMOV \t%%15,%%14");
  87. }
  88. _LPAREN parameter _RPAREN body
  89. {
  90. clear_symbols(fun_idx + 1);
  91. var_num = 0;
  92.  
  93. code("\n@%s_exit:", $2);
  94. code("\n\t\tMOV \t%%14,%%15");
  95. code("\n\t\tPOP \t%%14");
  96. code("\n\t\tRET");
  97. }
  98. ;
  99.  
  100. parameter
  101. : /* empty */
  102. { set_atr1(fun_idx, 0); }
  103.  
  104. | _TYPE _ID
  105. {
  106. insert_symbol($2, PAR, $1, 1, NO_ATR);
  107. set_atr1(fun_idx, 1);
  108. set_atr2(fun_idx, $1);
  109. }
  110. ;
  111.  
  112. body
  113. : _LBRACKET variable_list
  114. {
  115. if(var_num)
  116. code("\n\t\tSUBS\t%%15,$%d,%%15", 4*var_num);
  117. code("\n@%s_body:", get_name(fun_idx));
  118. }
  119. statement_list _RBRACKET
  120. ;
  121.  
  122. variable_list
  123. : /* empty */
  124. | variable_list variable
  125. ;
  126.  
  127. variable
  128. : _TYPE _ID _SEMICOLON
  129. {
  130. if(lookup_symbol($2, VAR|PAR) == NO_INDEX)
  131. insert_symbol($2, VAR, $1, ++var_num, NO_ATR);
  132. else
  133. err("redefinition of '%s'", $2);
  134. }
  135. ;
  136.  
  137. gvariable_list
  138. : /* empty */
  139. | gvariable_list gvariable
  140. ;
  141.  
  142. gvariable
  143. : _TYPE _ID _SEMICOLON
  144. {
  145. if(lookup_symbol($2, GVAR) == NO_INDEX){
  146. insert_symbol($2, GVAR, $1, NO_ATR, NO_ATR);
  147. code("\n%s:", $2);
  148. code("\n\t\tWORD\t1");}
  149. else
  150. err("redefinition of '%s'", $2);
  151. }
  152. ;
  153. statement_list
  154. : /* empty */
  155. | statement_list statement
  156. ;
  157.  
  158. statement
  159. : compound_statement
  160. | assignment_statement
  161. | if_statement
  162. | return_statement
  163. | increment_statement
  164. ;
  165.  
  166. increment_statement
  167. : _ID _INC _SEMICOLON{
  168. int idx = lookup_symbol($1, (VAR|PAR|GVAR));
  169. if (idx != -1){
  170. if(get_type(idx) == INT){
  171. code("\n\t\tADDS\t");
  172. }else{
  173. code("\n\t\tADDU\t");
  174. }
  175. gen_sym_name(idx);
  176. code(", $1, ");
  177. gen_sym_name(idx);
  178.  
  179. }
  180. else
  181. err("%s not defined", $1);
  182. }
  183. ;
  184. compound_statement
  185. : _LBRACKET statement_list _RBRACKET
  186. ;
  187.  
  188. assignment_statement
  189. : _ID _ASSIGN num_exp_f _SEMICOLON
  190. {
  191. int idx = lookup_symbol($1, (VAR|PAR|GVAR));
  192. if(idx == NO_INDEX)
  193. err("invalid lvalue '%s' in assignment", $1);
  194. else
  195. if(get_type(idx) != get_type($3))
  196. err("incompatible types in assignment");
  197. gen_mov($3, idx);
  198. }
  199. ;
  200.  
  201. num_exp
  202. : exp
  203. | num_exp _AROP exp
  204. {
  205. if(get_type($1) != get_type($3))
  206. err("invalid operands: arithmetic operation");
  207. int t1 = get_type($1);
  208. code("\n\t\t%s\t", ar_instructions[$2 + (t1 - 1) * AROP_NUMBER]);
  209. gen_sym_name($1);
  210. code(",");
  211. gen_sym_name($3);
  212. code(",");
  213. free_if_reg($3);
  214. free_if_reg($1);
  215. $$ = take_reg();
  216. gen_sym_name($$);
  217. set_type($$, t1);
  218. }
  219. ;
  220.  
  221. exp
  222. : literal
  223.  
  224. | _ID
  225. {
  226. $$ = lookup_symbol($1, (VAR|PAR|GVAR));
  227. if($$ == NO_INDEX)
  228. err("'%s' undeclared", $1);
  229. }
  230. | _ID _INC
  231. {
  232. $$ = lookup_symbol($1, (VAR|PAR|GVAR));
  233. if($$ == NO_INDEX)
  234. err("'%s' undeclared", $1);
  235. else
  236. {
  237. inc_list[trenutni_inc++] = $$;
  238. }
  239.  
  240. }
  241.  
  242. | function_call
  243. {
  244. $$ = take_reg();
  245. gen_mov(FUN_REG, $$);
  246. }
  247.  
  248. | _LPAREN num_exp_f _RPAREN
  249. { $$ = $2; }
  250. ;
  251.  
  252. literal
  253. : _INT_NUMBER
  254. { $$ = insert_literal($1, INT); }
  255.  
  256. | _UINT_NUMBER
  257. { $$ = insert_literal($1, UINT); }
  258. ;
  259.  
  260. function_call
  261. : _ID
  262. {
  263. fcall_idx = lookup_symbol($1, FUN);
  264. if(fcall_idx == -1)
  265. err("'%s' is not a function", $1);
  266. }
  267. _LPAREN argument _RPAREN
  268. {
  269. if(get_atr1(fcall_idx) != $4)
  270. err("wrong number of arguments");
  271. code("\n\t\t\tCALL\t%s", get_name(fcall_idx));
  272. if($4 > 0)
  273. code("\n\t\t\tADDS\t%%15,$%d,%%15", $4 * 4);
  274. set_type(FUN_REG, get_type(fcall_idx));
  275. $$ = FUN_REG;
  276. }
  277. ;
  278.  
  279. argument
  280. : /* empty */
  281. { $$ = 0; }
  282.  
  283. | num_exp_f
  284. {
  285. if(get_atr2(fcall_idx) != get_type($1))
  286. err("incompatible type for argument");
  287. free_if_reg($1);
  288. code("\n\t\t\tPUSH\t");
  289. gen_sym_name($1);
  290. $$ = 1;
  291. }
  292. ;
  293.  
  294. if_statement
  295. : if_part %prec ONLY_IF
  296. { code("\n@exit%d:", $1); }
  297.  
  298. | if_part _ELSE statement
  299. { code("\n@exit%d:", $1); }
  300. ;
  301.  
  302. if_part
  303. : _IF _LPAREN
  304. {
  305. $<i>$ = ++lab_num;
  306. code("\n@if%d:", lab_num);
  307. }
  308. rel_exp
  309. {
  310. code("\n\t\t%s\t@false%d", opp_jumps[$4], $<i>3);
  311. code("\n@true%d:", $<i>3);
  312. }
  313. _RPAREN statement
  314. {
  315. code("\n\t\tJMP \t@exit%d", $<i>3);
  316. code("\n@false%d:", $<i>3);
  317. $$ = $<i>3;
  318. }
  319. ;
  320.  
  321. rel_exp
  322. : num_exp_f _RELOP num_exp_f
  323. {
  324. if(get_type($1) != get_type($3))
  325. err("invalid operands: relational operator");
  326. $$ = $2 + ((get_type($1) - 1) * RELOP_NUMBER);
  327. gen_cmp($1, $3);
  328. }
  329. ;
  330.  
  331. return_statement
  332. : _RETURN num_exp_f _SEMICOLON
  333. {
  334. if(get_type(fun_idx) != get_type($2))
  335. err("incompatible types in return");
  336. gen_mov($2, FUN_REG);
  337. code("\n\t\tJMP \t@%s_exit", get_name(fun_idx));
  338. }
  339. ;
  340.  
  341. num_exp_f
  342. : num_exp {
  343. $$ = $1;
  344. if(trenutni_inc > 0){
  345. for(int j = 0; j < trenutni_inc; j++){
  346. if(get_type(inc_list[j]) == INT){
  347. code("\n\t\tADDS\t");
  348. }else{
  349. code("\n\t\tADDU\t");
  350. }
  351. gen_sym_name(inc_list[j]);
  352. code(", $1, ");
  353. gen_sym_name(inc_list[j]);
  354. inc_list[j] = 0;
  355. }
  356. }
  357. trenutni_inc = 0;
  358. }
  359. ;
  360. %%
  361.  
  362. int yyerror(char *s) {
  363. fprintf(stderr, "\nline %d: ERROR: %s", yylineno, s);
  364. error_count++;
  365. return 0;
  366. }
  367.  
  368. void warning(char *s) {
  369. fprintf(stderr, "\nline %d: WARNING: %s", yylineno, s);
  370. warning_count++;
  371. }
  372.  
  373. int main() {
  374. int synerr;
  375. init_symtab();
  376. output = fopen("output.asm", "w+");
  377.  
  378. synerr = yyparse();
  379.  
  380. clear_symtab();
  381. fclose(output);
  382.  
  383. if(warning_count)
  384. printf("\n%d warning(s).\n", warning_count);
  385.  
  386. if(error_count) {
  387. remove("output.asm");
  388. printf("\n%d error(s).\n", error_count);
  389. }
  390.  
  391. if(synerr)
  392. return -1; //syntax error
  393. else if(error_count)
  394. return error_count & 127; //semantic errors
  395. else if(warning_count)
  396. return (warning_count & 127) + 127; //warnings
  397. else
  398. return 0; //OK
  399. }
Advertisement
Add Comment
Please, Sign In to add comment