Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %{
- #include <stdio.h>
- #include <stdlib.h>
- #include "defs.h"
- #include "symtab.h"
- int yyparse(void);
- int yylex(void);
- int yyerror(char *s);
- void warning(char *s);
- int size = 2;
- int case_no = 0;
- int *niz_case;
- extern int yylineno;
- char char_buffer[CHAR_BUFFER_LENGTH];
- int error_count = 0;
- int warning_count = 0;
- int var_num = 0;
- int fun_idx = -1;
- int fcall_idx = -1;
- int comp = 0;
- int switch_type = -1;
- %}
- %union {
- int i;
- char *s;
- }
- %token <i> _TYPE
- %token _IF
- %token _ELSE
- %token _RETURN
- %token <s> _ID
- %token <s> _INT_NUMBER
- %token <s> _UINT_NUMBER
- %token _LPAREN
- %token _RPAREN
- %token _LBRACKET
- %token _RBRACKET
- %token _ASSIGN
- %token _BREAK
- %token _SWITCH
- %token _DEFAULT
- %token _CASE
- %token _COLON
- %token _SEMICOLON
- %token _FOR
- %token _INC
- %token <i> _AROP
- %token <i> _RELOP
- %type <i> type num_exp exp literal parameter for_statement
- %type <i> function_call argument rel_exp
- %nonassoc ONLY_IF
- %nonassoc _ELSE
- %%
- program
- : function_list
- {
- int idx;
- if((idx = lookup_symbol("main", FUN)) == -1)
- err("undefined reference to 'main'");
- else
- if(get_type(idx) != INT)
- warn("return type of 'main' is not int");
- }
- ;
- function_list
- : function
- | function_list function
- ;
- type
- : _TYPE
- { $$ = $1; }
- ;
- function
- : type _ID
- {
- if( (fun_idx = lookup_symbol($2, FUN)) == -1 )
- fun_idx = insert_symbol($2, FUN, $1, NO_ATTR);
- else
- err("redefinition of function '%s'", $2);
- }
- _LPAREN parameter _RPAREN
- {
- set_attr(fun_idx, $5);
- var_num = 0;
- }
- body
- {
- // izbaci iz tabele simbola sve lokalne simbole
- clear_symbols(fun_idx + 1);
- }
- ;
- parameter
- : /* empty */
- { $$ = 0; }
- | type _ID
- {
- insert_symbol($2, PAR, $1, 1);
- set_ptyp(fun_idx, $1);
- $$ = 1; // samo 1 parametar
- }
- ;
- body
- : _LBRACKET variable_list statement_list _RBRACKET
- ;
- variable_list
- : /* empty */
- | variable_list variable
- ;
- variable
- : type _ID _SEMICOLON
- {
- int idx = lookup_symbol($2, PAR|VAR);
- if(idx != -1 && get_ptyp(idx) == comp)
- err("redefinition of parameter or variable '%s'", $2);
- else{
- idx = insert_symbol($2, VAR, $1, ++var_num);
- set_ptyp(idx, comp);
- }
- }
- ;
- statement_list
- : /* empty */
- | statement_list statement
- ;
- statement
- : compound_statement
- | assignment_statement
- | if_statement
- | return_statement
- | for_statement
- | switch_statement
- ;
- switch_statement
- : _SWITCH _LPAREN _ID
- {
- int idx;
- if((idx = lookup_symbol($3, (VAR|PAR))) == -1)
- err("'%s' undeclared", $3);
- switch_type = get_type(idx);
- }
- _RPAREN _LBRACKET case_statement _DEFAULT _COLON statement_list _BREAK _SEMICOLON _RBRACKET
- ;
- case_statement
- : case
- | case_statement case
- ;
- case
- : _CASE literal _COLON statement_list break
- {
- if(switch_type!=get_type($2)){
- err("Switch id and case type must match");
- }
- int i = 0;
- if(case_no>size){
- int *tmp;
- tmp = (int*)malloc(case_no* sizeof(int));
- for(i = 0; i < size; i++){
- tmp[i] = niz_case[i];
- }
- *niz_case = *tmp;
- size = case_no;
- free(tmp);
- }
- niz_case[case_no] = $2;
- if(case_no>0){
- for(i = 0; i < 50; i++){
- if(i!=case_no) {
- if(get_name(niz_case[i]) == get_name(niz_case[case_no])){
- err("Every case must have different value");
- break;
- }
- }
- }
- }
- case_no++;
- }
- ;
- break
- :
- | _BREAK _SEMICOLON
- ;
- for_statement
- : _FOR _LPAREN type _ID _ASSIGN literal
- {
- if($3 != get_type($6)){
- err("Iterator and literal have different types");
- }
- int idx = insert_symbol($4, VAR, $3,++var_num);
- $<i>$ = idx;
- }
- _SEMICOLON rel_exp _SEMICOLON _ID _INC _RPAREN
- {
- if(*($4) != *($11)){
- err("You must increment the same variable %s %s ",$4, $11 );
- }
- } statement {clear_symbols($<i>6);}
- ;
- compound_statement
- : _LBRACKET {comp++; $<i>$ = get_last_element();} variable_list statement_list {comp--; $<i>$ = $<i>2; clear_symbols($<i>$ + 1); } _RBRACKET
- ;
- assignment_statement
- : _ID _ASSIGN num_exp _SEMICOLON
- {
- int idx = -1;
- if((idx = lookup_symbol($1, (VAR|PAR))) == -1)
- err("invalid lvalue in assignment");
- if(get_type(idx) != get_type($3))
- err("incompatible types in assignment");
- }
- ;
- num_exp
- : exp
- | num_exp _AROP exp
- {
- if(get_type($1) != get_type($3))
- err("invalid operands to "
- "arithmetic operation");
- }
- ;
- exp
- : literal
- | _ID
- {
- if(($$ = lookup_symbol($1, (VAR|PAR))) == -1)
- err("'%s' undeclared", $1);
- }
- | function_call
- | _LPAREN num_exp _RPAREN
- { $$ = $2; }
- ;
- literal
- : _INT_NUMBER
- { $$ = insert_literal($1, INT); }
- | _UINT_NUMBER
- { $$ = insert_literal($1, UINT); }
- ;
- function_call
- : _ID
- {
- if((fcall_idx = lookup_symbol($1, FUN)) == -1)
- err("'%s' is not a function", $1);
- }
- _LPAREN argument _RPAREN
- {
- if (get_attr(fcall_idx) != $4)
- err("wrong number of arguments to function '%s'",
- get_name(fcall_idx));
- //povratna vrednost funkcije se nalazi u %13
- set_reg_type(FUN_REG, get_type(fcall_idx));
- $$ = FUN_REG;
- }
- ;
- argument
- : /* empty */
- { $$ = 0; }
- | num_exp
- {
- if(get_ptyp(fcall_idx) != get_type($1))
- err("incompatible type for argument in '%s'",
- get_name(fcall_idx));
- $$ = 1;
- }
- ;
- if_statement
- : if_part %prec ONLY_IF
- | if_part _ELSE statement
- ;
- if_part
- : _IF _LPAREN rel_exp _RPAREN statement
- ;
- rel_exp
- : num_exp _RELOP num_exp
- {
- if(get_type($1) != get_type($3))
- err("invalid operands to relational "
- "operator");
- }
- ;
- return_statement
- : _RETURN num_exp _SEMICOLON
- {
- if(get_type(fun_idx) != get_type($2))
- err("incompatible types in return");
- }
- ;
- %%
- int yyerror(char *s) {
- fprintf(stderr, "\nline %d: ERROR: %s", yylineno, s);
- error_count++;
- return 0;
- }
- void warning(char *s) {
- fprintf(stderr,"\nline %d: WARNING: %s", yylineno, s);
- warning_count++;
- }
- int main() {
- int synerr;
- init_symtab();
- niz_case = (int*)malloc(size* sizeof(int));
- synerr = yyparse();
- clear_symtab();
- if(warning_count)
- printf("\n%d warning(s).\n", warning_count);
- if(error_count)
- printf("\n%d error(s).\n", error_count);
- free(niz_case);
- if (synerr)
- return -1;
- else
- return error_count;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement