%{ /* Prvi deo prvog dela ove datoteke se doslovno prenosi na pocetak y.tab.c fajla, slicno kao i kod lex-a Ovde ukljucujemo neka zaglavlja, definisemo funkciju yyerror i deklarisemo yylex sto je obavezno */ #include #include void yyerror(char *str) { fprintf(stderr, "Pojavila se greska: %s\n", str); exit(EXIT_FAILURE); } int yylex(); %} /* Navodimo sve tokene (osim onih jednokarakterskih) kako bi yacc znao sta su neterminali a sta terminali (tokeni) */ %token num /* Kako smo koristili viseznacnu gramatiku da bi razresili shift-reduce konflikte koji bi se javili pri prevodjenju, definisemo asocijativnost i prioritet sledecih tokena */ %left '+' '-' %left '*' '/' %left UMINUS %% /* uveli smo novi startni simbol kako bi nam se ispisala vrednos izraza */ E_P : E { printf("Vrednost izraza je %d\n", $1); } ; /* koristili smo viseznacnu gramatiku i za svako reduce pravilo smo definisali akcije Svaki token ima vrednost yylval koja je njemu pridruzena Po default-u ova vrednost je tipa int $$ - vrednost desne stane pravila $i - vrednost i-tog tokena na desnoj strani pravila */ E : E '+' E { $$ = $1 + $3; } | E '-' E { $$ = $1 - $3; } | E '*' E { $$ = $1 * $3; } | E '/' E { if ($3 == 0) yyerror("Deljenje sa nulom"); $$ = $1 / $3; } | '(' E ')' { $$ = $2; } /* Kako unarni minus ima veci prioritet i od +, -, * i / Uveli smo dodatni "lazni" token UMINUS sa vecim prioritetom, a za nas minus koji se pojavljuje u pravilima preciziramo da ima asocijativnos i prioritet kao UMINUS */ | '-' E %prec UMINUS { $$ = -$2; } | num { $$ = $1; } ; %% /* Main funkcija */ int main() { return yyparse(); }