Advertisement
Mihailo21

prpry

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