Mihailo21

Postavka

Nov 24th, 2023
14
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.65 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. %}
  20.  
  21. %union {
  22. int i;
  23. char *s;
  24. }
  25.  
  26. %token <i> _TYPE
  27. %token _IF
  28. %token _ELSE
  29. %token _RETURN
  30. %token <s> _ID
  31. %token <s> _INT_NUMBER
  32. %token <s> _UINT_NUMBER
  33. %token _LPAREN
  34. %token _RPAREN
  35. %token _LBRACKET
  36. %token _RBRACKET
  37. %token _ASSIGN
  38. %token _SEMICOLON
  39. %token <i> _AROP
  40. %token <i> _RELOP
  41.  
  42. %type <i> num_exp exp literal function_call argument rel_exp
  43.  
  44. %nonassoc ONLY_IF
  45. %nonassoc _ELSE
  46.  
  47. %%
  48.  
  49. program
  50. : function_list
  51. {
  52. if(lookup_symbol("main", FUN) == NO_INDEX)
  53. err("undefined reference to 'main'");
  54. }
  55. ;
  56.  
  57. function_list
  58. : function
  59. | function_list function
  60. ;
  61.  
  62. function
  63. : _TYPE _ID
  64. {
  65. fun_idx = lookup_symbol($2, FUN);
  66. if(fun_idx == NO_INDEX)
  67. fun_idx = insert_symbol($2, FUN, $1, NO_ATR, NO_ATR);
  68. else
  69. err("redefinition of function '%s'", $2);
  70. }
  71. _LPAREN parameter _RPAREN body
  72. {
  73. clear_symbols(fun_idx + 1);
  74. var_num = 0;
  75. }
  76. ;
  77.  
  78. parameter
  79. : /* empty */
  80. { set_atr1(fun_idx, 0); }
  81.  
  82. | _TYPE _ID
  83. {
  84. insert_symbol($2, PAR, $1, 1, NO_ATR);
  85. set_atr1(fun_idx, 1);
  86. set_atr2(fun_idx, $1);
  87. }
  88. ;
  89.  
  90. body
  91. : _LBRACKET variable_list statement_list _RBRACKET
  92. ;
  93.  
  94. variable_list
  95. : /* empty */
  96. | variable_list variable
  97. ;
  98.  
  99. variable
  100. : _TYPE _ID _SEMICOLON
  101. {
  102. if(lookup_symbol($2, VAR|PAR) == NO_INDEX)
  103. insert_symbol($2, VAR, $1, ++var_num, NO_ATR);
  104. else
  105. err("redefinition of '%s'", $2);
  106. }
  107. ;
  108.  
  109. statement_list
  110. : /* empty */
  111. | statement_list statement
  112. ;
  113.  
  114. statement
  115. : compound_statement
  116. | assignment_statement
  117. | if_statement
  118. | return_statement
  119. ;
  120.  
  121. compound_statement
  122. : _LBRACKET statement_list _RBRACKET
  123. ;
  124.  
  125. assignment_statement
  126. : _ID _ASSIGN num_exp _SEMICOLON
  127. {
  128. int idx = lookup_symbol($1, VAR|PAR);
  129. if(idx == NO_INDEX)
  130. err("invalid lvalue '%s' in assignment", $1);
  131. else
  132. if(get_type(idx) != get_type($3))
  133. err("incompatible types in assignment");
  134. }
  135. ;
  136.  
  137. num_exp
  138. : exp
  139. | num_exp _AROP exp
  140. {
  141. if(get_type($1) != get_type($3))
  142. err("invalid operands: arithmetic operation");
  143. }
  144. ;
  145.  
  146. exp
  147. : literal
  148. | _ID
  149. {
  150. $$ = lookup_symbol($1, VAR|PAR);
  151. if($$ == NO_INDEX)
  152. err("'%s' undeclared", $1);
  153. }
  154. | function_call
  155. | _LPAREN num_exp _RPAREN
  156. { $$ = $2; }
  157. ;
  158.  
  159. literal
  160. : _INT_NUMBER
  161. { $$ = insert_literal($1, INT); }
  162.  
  163. | _UINT_NUMBER
  164. { $$ = insert_literal($1, UINT); }
  165. ;
  166.  
  167. function_call
  168. : _ID
  169. {
  170. fcall_idx = lookup_symbol($1, FUN);
  171. if(fcall_idx == NO_INDEX)
  172. err("'%s' is not a function", $1);
  173. }
  174. _LPAREN argument _RPAREN
  175. {
  176. if(get_atr1(fcall_idx) != $4)
  177. err("wrong number of args to function '%s'",
  178. get_name(fcall_idx));
  179. set_type(FUN_REG, get_type(fcall_idx));
  180. $$ = FUN_REG;
  181. }
  182. ;
  183.  
  184. argument
  185. : /* empty */
  186. { $$ = 0; }
  187.  
  188. | num_exp
  189. {
  190. if(get_atr2(fcall_idx) != get_type($1))
  191. err("incompatible type for argument in '%s'",
  192. get_name(fcall_idx));
  193. $$ = 1;
  194. }
  195. ;
  196.  
  197. if_statement
  198. : if_part %prec ONLY_IF
  199. | if_part _ELSE statement
  200. ;
  201.  
  202. if_part
  203. : _IF _LPAREN rel_exp _RPAREN statement
  204. ;
  205.  
  206. rel_exp
  207. : num_exp _RELOP num_exp
  208. {
  209. if(get_type($1) != get_type($3))
  210. err("invalid operands: relational operator");
  211. }
  212. ;
  213.  
  214. return_statement
  215. : _RETURN num_exp _SEMICOLON
  216. {
  217. if(get_type(fun_idx) != get_type($2))
  218. err("incompatible types in return");
  219. }
  220. ;
  221.  
  222. %%
  223.  
  224. int yyerror(char *s) {
  225. fprintf(stderr, "\nline %d: ERROR: %s", yylineno, s);
  226. error_count++;
  227. return 0;
  228. }
  229.  
  230. void warning(char *s) {
  231. fprintf(stderr, "\nline %d: WARNING: %s", yylineno, s);
  232. warning_count++;
  233. }
  234.  
  235. int main() {
  236. int synerr;
  237. init_symtab();
  238.  
  239. synerr = yyparse();
  240.  
  241. clear_symtab();
  242.  
  243. if(warning_count)
  244. printf("\n%d warning(s).\n", warning_count);
  245.  
  246. if(error_count)
  247. printf("\n%d error(s).\n", error_count);
  248.  
  249. if(synerr)
  250. return -1; //syntax error
  251. else
  252. return error_count; //semantic errors
  253. }
  254.  
  255.  
Add Comment
Please, Sign In to add comment