Advertisement
Guest User

vezba 7

a guest
Dec 4th, 2016
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
BNF 6.88 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.   int size = 2;
  12.  
  13.   int case_no = 0;
  14.   int *niz_case;
  15.   extern int yylineno;
  16.   char char_buffer[CHAR_BUFFER_LENGTH];  
  17.   int error_count = 0;
  18.   int warning_count = 0;
  19.   int var_num = 0;
  20.   int fun_idx = -1;
  21.   int fcall_idx = -1;
  22.   int comp = 0;
  23.   int switch_type = -1;
  24.  
  25.  
  26. %}
  27.  
  28. %union {
  29.   int i;
  30.   char *s;
  31. }
  32.  
  33. %token <i> _TYPE
  34. %token _IF
  35. %token _ELSE
  36. %token _RETURN
  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 _BREAK
  46. %token _SWITCH
  47. %token _DEFAULT
  48. %token _CASE
  49. %token _COLON
  50. %token _SEMICOLON
  51. %token _FOR
  52. %token _INC
  53. %token <i> _AROP
  54. %token <i> _RELOP
  55.  
  56. %type <i> type num_exp exp literal parameter for_statement
  57. %type <i> function_call argument rel_exp
  58.  
  59. %nonassoc ONLY_IF
  60. %nonassoc _ELSE
  61.  
  62. %%
  63.  
  64. program
  65.   : function_list
  66.       {  
  67.         int idx;
  68.         if((idx = lookup_symbol("main", FUN)) == -1)
  69.           err("undefined reference to 'main'");
  70.         else
  71.           if(get_type(idx) != INT)
  72.             warn("return type of 'main' is not int");
  73.        }
  74.   ;
  75.  
  76. function_list
  77.   : function
  78.   | function_list function
  79.   ;
  80.  
  81. type
  82.   : _TYPE
  83.       {  $$ = $1; }
  84.   ;
  85.  
  86. function
  87.   : type _ID
  88.       {
  89.         if( (fun_idx = lookup_symbol($2, FUN)) == -1 )
  90.           fun_idx = insert_symbol($2, FUN, $1, NO_ATTR);
  91.         else
  92.           err("redefinition of function '%s'", $2);
  93.       }
  94.     _LPAREN parameter _RPAREN
  95.       {
  96.         set_attr(fun_idx, $5);
  97.         var_num = 0;
  98.       }
  99.     body
  100.       {  
  101.         // izbaci iz tabele simbola sve lokalne simbole
  102.         clear_symbols(fun_idx + 1);
  103.       }
  104.   ;
  105.  
  106. parameter
  107.   : /* empty */
  108.       { $$ = 0; }
  109.  
  110.   | type _ID
  111.       {
  112.         insert_symbol($2, PAR, $1, 1);
  113.         set_ptyp(fun_idx, $1);
  114.         $$ = 1; // samo 1 parametar
  115.       }
  116.   ;
  117.  
  118. body
  119.   : _LBRACKET variable_list statement_list _RBRACKET
  120.   ;
  121.  
  122. variable_list
  123.   : /* empty */
  124.   | variable_list variable
  125.   ;
  126.  
  127. variable
  128.   : type _ID _SEMICOLON
  129.       {
  130.         int idx = lookup_symbol($2, PAR|VAR);
  131.         if(idx != -1 && get_ptyp(idx) == comp)
  132.            err("redefinition of parameter or variable '%s'", $2);
  133.         else{
  134.          idx = insert_symbol($2, VAR, $1, ++var_num);
  135.          set_ptyp(idx, comp);
  136.         }
  137.       }
  138.   ;
  139.  
  140. statement_list
  141.   : /* empty */
  142.   | statement_list statement
  143.   ;
  144.  
  145. statement
  146.     : compound_statement
  147.     | assignment_statement
  148.     | if_statement
  149.     | return_statement
  150.     | for_statement
  151.     | switch_statement
  152.     ;
  153.  
  154. switch_statement
  155.     :   _SWITCH _LPAREN _ID
  156.         {
  157.             int idx;
  158.            
  159.             if((idx = lookup_symbol($3, (VAR|PAR))) == -1)
  160.                 err("'%s' undeclared", $3);
  161.             switch_type = get_type(idx);
  162.         }
  163.  
  164. _RPAREN _LBRACKET case_statement _DEFAULT _COLON statement_list _BREAK _SEMICOLON _RBRACKET
  165.     ;
  166. case_statement
  167.     :   case
  168.     |   case_statement  case
  169.     ;
  170. case
  171.     : _CASE literal _COLON statement_list break
  172.         {
  173.             if(switch_type!=get_type($2)){
  174.                 err("Switch id and case type must match");
  175.             }
  176.             int i = 0;
  177.             if(case_no>size){
  178.                 int *tmp;
  179.                 tmp = (int*)malloc(case_no* sizeof(int));
  180.                 for(i = 0; i < size; i++){
  181.                     tmp[i] = niz_case[i];
  182.                 }
  183.                 *niz_case = *tmp;
  184.                 size = case_no;
  185.                 free(tmp);
  186.             }
  187.             niz_case[case_no] = $2;
  188.             if(case_no>0){
  189.                
  190.                 for(i = 0; i < 50; i++){
  191.                     if(i!=case_no) {
  192.                         if(get_name(niz_case[i]) == get_name(niz_case[case_no])){
  193.                             err("Every case must have different value");
  194.                             break;
  195.                         }
  196.                     }
  197.                 }
  198.             }
  199.             case_no++;
  200.         }
  201.     ;
  202. break
  203.     :
  204.     | _BREAK _SEMICOLON
  205.     ;
  206. for_statement
  207.     : _FOR _LPAREN type _ID _ASSIGN literal
  208.     {
  209.         if($3 != get_type($6)){
  210.             err("Iterator and literal have different types");
  211.         }
  212.         int idx = insert_symbol($4, VAR, $3,++var_num);
  213.         $<i>$ = idx;
  214.     }
  215.      _SEMICOLON rel_exp _SEMICOLON _ID _INC _RPAREN
  216.     {
  217.        
  218.         if(*($4) != *($11)){
  219.             err("You must increment the same variable %s %s ",$4, $11 );
  220.         }
  221.        
  222.        
  223.     } statement {clear_symbols($<i>6);}
  224.     ;
  225.  
  226.    
  227.  
  228. compound_statement
  229.   : _LBRACKET {comp++; $<i>$ = get_last_element();} variable_list statement_list  {comp--; $<i>$ = $<i>2; clear_symbols($<i>$ + 1); } _RBRACKET
  230.   ;
  231.  
  232. assignment_statement
  233.   : _ID _ASSIGN num_exp _SEMICOLON
  234.       {
  235.         int idx = -1;
  236.         if((idx = lookup_symbol($1, (VAR|PAR))) == -1)
  237.           err("invalid lvalue in assignment");
  238.         if(get_type(idx) != get_type($3))
  239.           err("incompatible types in assignment");
  240.       }
  241.   ;
  242.  
  243. num_exp
  244.   : exp
  245.   | num_exp _AROP exp
  246.       {
  247.         if(get_type($1) != get_type($3))
  248.           err("invalid operands to "
  249.               "arithmetic operation");
  250.       }
  251.   ;
  252.  
  253. exp
  254.   : literal
  255.   | _ID
  256.       {
  257.         if(($$ = lookup_symbol($1, (VAR|PAR))) == -1)
  258.           err("'%s' undeclared", $1);
  259.       }
  260.   | function_call
  261.   | _LPAREN num_exp _RPAREN
  262.       {  $$ = $2; }
  263.   ;
  264.  
  265. literal
  266.   : _INT_NUMBER
  267.       {  $$ = insert_literal($1, INT); }
  268.  
  269.   | _UINT_NUMBER
  270.       {  $$ = insert_literal($1, UINT); }
  271.   ;
  272.  
  273. function_call
  274.   : _ID
  275.       {
  276.         if((fcall_idx = lookup_symbol($1, FUN)) == -1)
  277.             err("'%s' is not a function", $1);
  278.       }
  279.     _LPAREN argument _RPAREN
  280.       {
  281.         if (get_attr(fcall_idx) != $4)
  282.            err("wrong number of arguments to function '%s'",
  283.               get_name(fcall_idx));
  284.         //povratna vrednost funkcije se nalazi u %13
  285.         set_reg_type(FUN_REG, get_type(fcall_idx));
  286.         $$ = FUN_REG;
  287.       }
  288.   ;
  289.  
  290. argument
  291.   : /* empty */
  292.     { $$ = 0; }
  293.  
  294.   | num_exp
  295.     {
  296.       if(get_ptyp(fcall_idx) != get_type($1))
  297.         err("incompatible type for argument in '%s'",
  298.           get_name(fcall_idx));
  299.       $$ = 1;
  300.     }
  301.   ;
  302.  
  303. if_statement
  304.   : if_part %prec ONLY_IF
  305.   | if_part _ELSE statement
  306.   ;
  307.  
  308. if_part
  309.   : _IF _LPAREN rel_exp _RPAREN statement
  310.   ;
  311.  
  312. rel_exp
  313.   : num_exp _RELOP num_exp
  314.       {
  315.         if(get_type($1) != get_type($3))
  316.           err("invalid operands to relational "
  317.             "operator");
  318.       }
  319.   ;
  320.  
  321. return_statement
  322.   : _RETURN num_exp _SEMICOLON
  323.       {
  324.         if(get_type(fun_idx) != get_type($2))
  325.           err("incompatible types in return");
  326.       }
  327.   ;
  328.  
  329. %%
  330.  
  331. int yyerror(char *s) {
  332.   fprintf(stderr, "\nline %d: ERROR: %s", yylineno, s);
  333.   error_count++;
  334.   return 0;
  335. }
  336.  
  337. void warning(char *s) {
  338.   fprintf(stderr,"\nline %d: WARNING: %s", yylineno, s);
  339.   warning_count++;
  340. }
  341.  
  342. int main() {
  343.   int synerr;
  344.   init_symtab();
  345.   niz_case = (int*)malloc(size* sizeof(int));
  346.   synerr = yyparse();
  347.  
  348.   clear_symtab();
  349.  
  350.   if(warning_count)
  351.     printf("\n%d warning(s).\n", warning_count);
  352.  
  353.   if(error_count)
  354.     printf("\n%d error(s).\n", error_count);
  355.  
  356.     free(niz_case);
  357.   if (synerr)
  358.     return -1;
  359.   else
  360.     return error_count;
  361. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement