%{ #include #include #include #include "skup.h" /* za potrebe debagovanja */ #define YYDEBUG 1 /* fja za obradu gresaka */ void yyerror(char *s) { fprintf(stderr, "Sintaksna greska: %s\n", s); exit(EXIT_FAILURE); } /* leksicki analizator */ extern int yylex(); /* promenljiva */ typedef struct { char *ime; Skup *skup; } promenljiva; /* maksimalan broj promenljivih u programu */ #define MAX 64 /* trenutno definisanih promenljivih */ int broj_promenljivih = 0; /* niz do sada definisanih promenljivih */ promenljiva tablica_simbola[MAX]; /* fja koja vraca skup cije je ime "ime" */ Skup* vrati_skup(char *ime) { int i = 0; for(; i= MAX) yyerror("Previse promenljivih"); tablica_simbola[broj_promenljivih].ime = ime; tablica_simbola[broj_promenljivih++].skup = s; } %} %union { int broj; char *ime; Skup *s; } %token id_token %token print_token oddo_token unija_token presek_token check_token card_token %token num_token %type Skup Niz Izraz %left '~' %left '\\' %left presek_token %left unija_token %% /* program je niz naredbi */ Program: Program Naredba { } /* ili jedna naredba */ | Naredba { } ; /* Naredba moze biti naredba inicijalizacije skupa */ Naredba: id_token '=' Izraz ';' { zapamti_promenljivu($1, $3); } /* stampanje nekog skupa */ | print_token Izraz ';' { printf("{"); prikazi_stablo($2); printf("\b\b}\n"); oslobodi_stablo($2); } /* provera da li neki element pripada skupu */ | check_token num_token ':' Izraz ';' { if (pretrazi_stablo($4, $2)==NULL) printf("False\n"); else printf("True\n"); oslobodi_stablo($4); } /* provera da li je neki skup podskup drugog */ | check_token Izraz '<' Izraz ';' { if (podskup($2, $4)) printf("True\n"); else printf("False\n"); oslobodi_stablo($2); oslobodi_stablo($4); } /* odredjivanje kardinalnosti skupa */ | card_token Izraz ';' { printf("%d\n", broj_elemenata($2)); oslobodi_stablo($2); } ; /* Prost skup moze biti inicijalizovan na tri nacina: Nizom elemenata */ Skup: '{' Niz '}'{ $$ = $2; } /* praznim skupom */ | '{' '}' { $$ = NULL; } /* sekvencom */ | num_token oddo_token num_token { int i; $$ = NULL; for(i = $1; i <= $3; i++) $$ = dodaj_u_stablo($$, i); } ; /* Niz elemenata sa separatorom zarez */ Niz: Niz ',' num_token { $$ = dodaj_u_stablo($1, $3); } | num_token { $$ = NULL; $$ = dodaj_u_stablo($$, $1); } ; /* Izraz nad skupovima moze biti unija dva skupa */ Izraz: Izraz unija_token Izraz { $$ = kreiraj_uniju($1, $3); oslobodi_stablo($3); } /* presek dva skupa */ | Izraz presek_token Izraz { $$ = kreiraj_presek($1, $3); oslobodi_stablo($3); } /* razlika dva skupa */ | Izraz '\\' Izraz { $$ = kreiraj_razliku($1, $3); oslobodi_stablo($3); } /* komplement skupa */ | '~' Izraz { Skup* p = vrati_skup("UniversalSet"); if (p == NULL) yyerror("Promenljiva UniversalSet nije definisana"); $$ = kreiraj_razliku(kopiraj_stablo(p), $2); oslobodi_stablo($2); } /* i kao izlaz iz rekurzije prost skup */ | Skup { $$ = $1; } /* ili neki vec definisan skup */ | id_token { Skup* p = vrati_skup($1); if (p == NULL) yyerror("Promenljiva nije definisana"); $$ = kopiraj_stablo(p); } ; %% int main() { yydebug = 0; yyparse(); return 0; }