Advertisement
Mihailo21

res

Nov 24th, 2023
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.53 KB | None | 0 0
  1. %{
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "defs.h"
  5. #include "symtab.h"
  6.  
  7. int yyparse(void);
  8. int yylex(void);
  9. int yyerror(char *s);
  10. void warning(char *s);
  11.  
  12. extern int yylineno;
  13. char char_buffer[CHAR_BUFFER_LENGTH];
  14. int error_count = 0;
  15. int warning_count = 0;
  16. int var_num = 0;
  17. int fun_idx = -1;
  18. int fcall_idx = -1;
  19. int idxPR=0; //promenljiva koja cuva indeks naseg _ID kad proveravama da li je istog tipa kao konstante
  20. %}
  21.  
  22. %union {
  23. int i;
  24. char *s;
  25. }
  26.  
  27. %token <i> _TYPE
  28. %token _IF
  29. %token _ELSE
  30. %token _RETURN
  31. %token _READ
  32. %token _DATA
  33. %token _DO
  34. %token _FROM
  35. %token _COMMA
  36.  
  37. %token <s> _ID
  38. %token <s> _INT_NUMBER
  39. %token <s> _UINT_NUMBER
  40. %token _LPAREN
  41. %token _RPAREN
  42. %token _LBRACKET
  43. %token _RBRACKET
  44. %token _ASSIGN
  45. %token _SEMICOLON
  46. %token <i> _AROP
  47. %token <i> _RELOP
  48.  
  49. %type <i> num_exp exp literal function_call argument rel_exp
  50.  
  51. %nonassoc ONLY_IF
  52. %nonassoc _ELSE
  53.  
  54. %%
  55.  
  56. program
  57. : function_list
  58. {
  59. if(lookup_symbol("main", FUN) == NO_INDEX)
  60. err("undefined reference to 'main'");
  61. }
  62. ;
  63.  
  64. function_list
  65. : function
  66. | function_list function
  67. ;
  68.  
  69. function
  70. : _TYPE _ID
  71. {
  72. fun_idx = lookup_symbol($2, FUN);
  73. if(fun_idx == NO_INDEX)
  74. fun_idx = insert_symbol($2, FUN, $1, NO_ATR, NO_ATR);
  75. else
  76. err("redefinition of function '%s'", $2);
  77. }
  78. _LPAREN parameter _RPAREN body
  79. {
  80. clear_symbols(fun_idx + 1);
  81. var_num = 0;
  82. }
  83. ;
  84.  
  85. parameter
  86. : /* empty */
  87. { set_atr1(fun_idx, 0); }
  88.  
  89. | _TYPE _ID
  90. {
  91. insert_symbol($2, PAR, $1, 1, NO_ATR);
  92. set_atr1(fun_idx, 1);
  93. set_atr2(fun_idx, $1);
  94. }
  95. ;
  96.  
  97. body
  98. : _LBRACKET variable_list statement_list _RBRACKET
  99. ;
  100.  
  101. variable_list
  102. : /* empty */
  103. | variable_list variable
  104. ;
  105.  
  106. variable
  107. : _TYPE _ID _SEMICOLON
  108. {
  109. if(lookup_symbol($2, VAR|PAR) == NO_INDEX)
  110. insert_symbol($2, VAR, $1, ++var_num, NO_ATR);
  111. else
  112. err("redefinition of '%s'", $2);
  113. }
  114. ;
  115.  
  116. statement_list
  117. : /* empty */
  118. | statement_list statement
  119. ;
  120.  
  121. statement
  122. : compound_statement
  123. | assignment_statement
  124. | if_statement
  125. | return_statement
  126. | read_statement
  127. ;
  128.  
  129. compound_statement
  130. : _LBRACKET statement_list _RBRACKET
  131. ;
  132.  
  133. assignment_statement
  134. : _ID _ASSIGN num_exp _SEMICOLON
  135. {
  136. int idx = lookup_symbol($1, VAR|PAR);
  137. if(idx == NO_INDEX)
  138. err("invalid lvalue '%s' in assignment", $1);
  139. else
  140. if(get_type(idx) != get_type($3))
  141. err("incompatible types in assignment");
  142. }
  143. ;
  144.  
  145. num_exp
  146. : exp
  147. | num_exp _AROP exp
  148. {
  149. if(get_type($1) != get_type($3))
  150. err("invalid operands: arithmetic operation");
  151. }
  152. ;
  153.  
  154. exp
  155. : literal
  156. | _ID
  157. {
  158. $$ = lookup_symbol($1, VAR|PAR);
  159. if($$ == NO_INDEX)
  160. err("'%s' undeclared", $1);
  161. }
  162. | function_call
  163. | _LPAREN num_exp _RPAREN
  164. { $$ = $2; }
  165. ;
  166.  
  167. literal
  168. : _INT_NUMBER
  169. { $$ = insert_literal($1, INT); }
  170.  
  171. | _UINT_NUMBER
  172. { $$ = insert_literal($1, UINT); }
  173. ;
  174.  
  175. function_call
  176. : _ID
  177. {
  178. fcall_idx = lookup_symbol($1, FUN);
  179. if(fcall_idx == NO_INDEX)
  180. err("'%s' is not a function", $1);
  181. }
  182. _LPAREN argument _RPAREN
  183. {
  184. if(get_atr1(fcall_idx) != $4)
  185. err("wrong number of args to function '%s'",
  186. get_name(fcall_idx));
  187. set_type(FUN_REG, get_type(fcall_idx));
  188. $$ = FUN_REG;
  189. }
  190. ;
  191.  
  192. argument
  193. : /* empty */
  194. { $$ = 0; }
  195.  
  196. | num_exp
  197. {
  198. if(get_atr2(fcall_idx) != get_type($1))
  199. err("incompatible type for argument in '%s'",
  200. get_name(fcall_idx));
  201. $$ = 1;
  202. }
  203. ;
  204.  
  205. if_statement
  206. : if_part %prec ONLY_IF
  207. | if_part _ELSE statement
  208. ;
  209.  
  210. if_part
  211. : _IF _LPAREN rel_exp _RPAREN statement
  212. ;
  213.  
  214. read_statement
  215. : _READ _ID
  216. {
  217. //provera da li je id prethodno deklarisan
  218. idxPR=lookup_symbol($2, VAR|PAR);
  219. if(idxPR == NO_INDEX)
  220. err("Promenljiva %s nije prethodno deklarisana ! [ERROR]",$2);
  221. }
  222. _FROM data_statements _DO statement
  223. ;
  224.  
  225. data_statements
  226. : data_statement
  227. | data_statements data_statement
  228. ;
  229.  
  230. data_statement
  231. : _DATA const_statements
  232. ;
  233.  
  234. const_statements
  235. : literal
  236. {
  237. if(get_type(idxPR) != get_type($1) )
  238. err("Promenljiva i konstanta nisu istog tipa !");
  239. }
  240. | const_statements _COMMA literal
  241. {
  242. if( get_type(idxPR) != get_type($3) )
  243. err("Promenljiva i konstanta nisu istog tipa !");
  244. }
  245. ;
  246.  
  247. rel_exp
  248. : num_exp _RELOP num_exp
  249. {
  250. if(get_type($1) != get_type($3))
  251. err("invalid operands: relational operator");
  252. }
  253. ;
  254.  
  255. return_statement
  256. : _RETURN num_exp _SEMICOLON
  257. {
  258. if(get_type(fun_idx) != get_type($2))
  259. err("incompatible types in return");
  260. }
  261. ;
  262.  
  263. %%
  264.  
  265. int yyerror(char *s) {
  266. fprintf(stderr, "\nline %d: ERROR: %s", yylineno, s);
  267. error_count++;
  268. return 0;
  269. }
  270.  
  271. void warning(char *s) {
  272. fprintf(stderr, "\nline %d: WARNING: %s", yylineno, s);
  273. warning_count++;
  274. }
  275.  
  276. int main() {
  277. int synerr;
  278. init_symtab();
  279.  
  280. synerr = yyparse();
  281.  
  282. clear_symtab();
  283.  
  284. if(warning_count)
  285. printf("\n%d warning(s).\n", warning_count);
  286.  
  287. if(error_count)
  288. printf("\n%d error(s).\n", error_count);
  289.  
  290. if(synerr)
  291. return -1; //syntax error
  292. else
  293. return error_count; //semantic errors
  294. }
  295.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement