TP3 - Analizor Sintactic (Unealtă Bison) : Partea I - Rappel (Bizon)
TP3 - Analizor Sintactic (Unealtă Bison) : Partea I - Rappel (Bizon)
Reguli de producț ie :
Non-terminal:prod1
|prod2
prod3
….
prodn
;
Simbolurile terminale sunt :
-Unită ț i lexicale (pe care trebuie să le declarăm obligatoriu în partea 2)
Sintaxă : %token nume-unitate-lexicală
Exemple : %tokenNB
%tokenID
- Des caractere între ghilimele: ‘+’, ‘a’…
1
- Ș iruri de caractere între ghilimele: "while"
Observaț ie: ParteaBloc principal ș i funcț ii auxiliare trebuie să conț ină o funcț ieyylex()
efectuând analiza lexică a programului sursă. Putem fie să scriem direct aceasta
funcț ia să fie utilizată funcț ia produsă de Flex.
%{
#include <stdio.h>
int yylex(void);
int yyerror (char*);
%}
%%
mot : S '$' {printf("mot corect"); getchar();}
;
'a'S'a'
'b'S'b'
'c'
;
%%
int yylex()
{
char c=getchar();
dacă (c=='a'||c=='b'||c=='c'||c=='$') return(c);
altfel printf("eroare lexicială");
}
int yyerror(char *s){
printf("%s \n",s);
return 0;
}
int main(){
yyparse();
return 0;}printf("\n");
return 0;
}
2
yylval. Această variabilă este instrumentul de bază de comunicare între Flex ș i Bison pe parcursul
analiza. Aș adar, trebuie să ne gândim să atribuim corect analiza lexicală.
Exemple:
%%
[0-9]+ {yylval=atoi(yytext); return NB ;}
%%
- În mod implicit, yylval este de tip întreg. Îi putem schimba tipul prin declaraț ia în
parte 2 a unei uniuni. Exemplu :
% uniune {
int intreg;
roată dublă;
char * ș ir ;
}yylval ;
În acest caz, putem stoca valori întregi, reale sau ș iruri de caractere.
caractere. Trebuie să tipizăm unităț ile lexicale ș i simbolurile neterminale pe care le folosim
atributul, adică exemplul:
% token <entier> NB
% token <secvenț ă> ID
% tip <entier> S
% tip <chaine> Expr
Partea III–Exerciț ii
Vrem să scriem cu ajutorul Flex ș i Bison un analizor sintactic care să permită recunoaș terea
instrucț iuni de forma următoare:
1, 2, 3.
Este vorba despre o listă de întregi separate prin virgule, terminându-se cu un punct ș i precedate
fie prin cuvântul sumă fie prin cuvântul produs.
3
1. Mai întâi, scrie ț i următorul fi ș ier de specifica ț ii Bison:
%{
#include<stdio.h>
int yylex(void);
%}
%%
listesom: NB
| listesom ',' NB
NB
| listeprod ',' NB
%%
return (0);
int main()
yyparse();
return 0;
4
2. Compila ț i fi ș ierele folosind op ț iunea –d, de exemplu bison -d nume.y
3. În caz de succes, fi ș ierele [Link] [Link] sunt generate în acela ș i
repertoriu.
4. Include fi ș ierul [Link].h în fi ș ierul de specifica ț ii Flex (acest fi ș ier con ț ine
descrierea unităț ilor lexicale utilizate).
5. Deschide ț i un nou fi ș ier text ș i introduce ț i următorul cod de specifica ț ii Flex:
%{
#include<stdio.h>
#include<math.h>
#include"[Link].h"
%}
%opț iune fără yywrap
%%
[0-9]+ {yylval=atoi(yytext); return NB;}
produs
{return SOM;}
[,|.] {return yytext[0];}
[$] {return FIN;}
[ ] {}
. {printf("Eroare");}
%%
6. Compila ț i acest fi ș ier cu Flex pentru a genera fi ș ierul [Link].c.
7. Include ț i fi ș ierul [Link].c în fi ș ierul de specifica ț ii Bison.
8. Compila ț i acum fi ș ierul [Link].c pentru a ob ț ine executabilul.
gcc [Link].c [Link].c -o prog
9. Testa ț i fi ș ierul .exe ob ț inut pentru a verifica dacă func ț ionează corect.
[Link]ă exerciț iul precedent pentru ca executabilul să afiseze suma (respectiv
produsul) al numerelor întregi care formează fiecare ș ir.
Anexe :
Variabile :
YYLVAL : variabilă predefinită care conț ine valoarea unităț ii lexicale recunoscute.
YYACCEPT: instrucț iune care permite oprirea analizorului sintactic. În acest
cas, yyparse returnează valoarea 0 indicând succesul.
YYABORT: instruc ț iune care permite de asemenea oprirea analizorului. yyparse
întoarce atunci1, ceea ce poate fi folosit pentru a semnala eș ecul analizei.
% ÎNCEPUT non-terminal : aceasta este o ac ț iune pentru a spune că non-terminalul este
axioma.
[Link] :
int yyparse () : funcț ia principală care lansează analizorul sintactic.
5
int yyerror(char *s) : funcț ie apelată de fiecare dată când analizorul se confruntă cu
o eroare.
Bibliografie[Link]