Documente Academic
Documente Profesional
Documente Cultură
Analiza Lexicala
Analiza Lexicala
Program sursa
Analizor
lexical
Atomi lexicali
1
Analizorul lexical
Atom
Caracter lexical
curent Analizor Analizor
lexical sintactic
Plaseaza
inapoi in
buffer
ultimul eroare eroare
caracter
Tabela de
simboluri
2
Analizorul lexical
a = b + 60 Analizor lexical
Atom lexical atribut
Pointer in tabela
de simboluri
<identificator, “a”>
<operator atribuire, -> <identificator, “b”>
<+,- > <numar, 60>
Analizor sintactic
4
Identificare atom lexical
Identificare atomi lexicali:
atomi lexicali specificati prin expresii regulate
1
e
a b
4 5 6
e
a b b
7 8 9 10
5
FLEX
program
*.l FLEX lex.yy.c
6
Specificatia FLEX
%{
cod C
%}
%%
reguli
%%
cod C
7
Specificatia FLEX
• Reguli: Instructiuni C
ER1 { actiune1 }
ER2 { actiune2 }
…
ERn { actiunen }
8
Specificatia FLEX
• Reguli:
sau
%%
reguli
”am” { printf(”Regula 1”);}
”3” { printf(”Regula 2”);}
”puncte” { printf(”Regula 3”);}
%%
Porneste
main() analizorul
lexical
{
yylex();
} 10
Determinarea potrivirilor in FLEX
%{
#include <stdio.h>
%}
%%
”ab” { printf(”Regula 1”);}
”abb” { printf(”Regula 2”);}
”abbc” { printf(”Regula 3”);}
%%
main()
{
yylex();
}
11
Expresii regulate in FLEX
“string” sirul “string”
. orice caracter diferit de '\n'
\. caracterul '.'
r 1r 2 concatenarea r1 cu r2
r1|r2 r1 + r2
(r) r 12
Expresii regulate in FLEX
13
Determinarea potrivirilor in FLEX
%{
#include <stdio.h>
%}
%%
”ab” { printf(”Regula 1”);}
”abb” { printf(”Regula 2”);}
”abbc” { printf(”Regula 3”);}
[a-c]+ { printf(”Regula 4”);}
%%
main()
{
yylex();
14
}
Determinarea potrivirilor in FLEX
%{
#include <stdio.h>
%}
%%
”ab” { printf(”Regula 1”);}
”abb” { printf(”Regula 2”);}
”abbc”/”cdd” { printf(”Regula 3”);}
[a-d]+ { printf(”Regula 4”);}
%%
main()
{
yylex();
15
}
yytext
%{
#include <stdio.h>
%}
%%
[0-9]+ { printf(“%s\n”, yytext); }
.|\n { }
%%
main()
{ yylex();
}
16
Macrodefinitii
%{
#include <stdio.h>
int nc = 0;
%}
cifra [0-9]
%%
{cifra} { nc ++; }
.|\n { }
%%
main()
{
yylex();
printf(”numar cifre = %d”, nc);
}
17
yyleng
%{
#include <stdio.h>
int nc = 0;
%}
cifra [0-9]
%%
{cifra} { nc += yyleng; }
.|\n { }
%%
main()
{
yylex();
printf(”numar cifre = %d”, nc);
} 18
Exemplu
%{
#include <stdio.h>
int nc = 0, nl = 0;
%}
cifra [0-9]
litera [a-zA-Z]
%%
{cifra}+ { nc += yyleng; }
{litera}+ { nl += yyleng; }
.|\n { }
%%
main()
{
yylex();
printf(”numar cifre = %d”, nc);
printf(”numar litere = %d”, nl);
}
19
Oprirea analizorului lexical
%{
%}
cifra [0-9]
semn [+-]?
Natural {cifra}+
Intreg {semn}{Natural}
Real {semn}{Natural}\.{Natural}?
%%
{Real} { printf("real\n"); return 1;}
{Natural} { printf(“natural\n"); return 2;}
{Intreg} { printf("intreg\n"); return 3;}
. { return -1; }
\n { return -2; }
%%
main(){
printf(“numar = %i\n", yylex());
}
20
Stari
• Declarare
%s S1 S2 ... Sn
sau
%x S1 S2 ... Sn
• BEGIN(nume);
21
Exemplu1 - stari
%{ char * a;
int nr_aparitii = 0, nr_cifre = 0;
%}
litera [A-Za-z]
cifra [0-9]
%s URMATOR
%%<INITIAL>{litera}+ { a = malloc(yyleng+1);
strcpy(a, yytext);
nr_aparitii = 1;
BEGIN (URMATOR); }
<URMATOR>{litera}+ {
if (!strcmp(a, yytext)) nr_aparitii++; }
{cifra} {numar_cifre++;}
%%main()
{ yylex();
printf(„primul cuvant %s apare de %i ori\n au fost
%i cifre”, a, numar_aparitii, numar_cifre);
free(a);}
22
Exemplu2 - stari
%{ char * a;
int nr_aparitii = 0, nr_cifre = 0;
%}
litera [A-Za-z]
cifra [0-9]
%x URMATOR
%%<INITIAL>{litera}+ { a = malloc(yyleng);
strcpy(a, yytext);
nr_aparitii = 1;
BEGIN (URMATOR); }
<URMATOR>{litera}+ {
if (!strcmp(a, yytext)) nr_aparitii++; }
{cifra} {numar_cifre++;}
%%main()
{ yylex();
printf(„primul cuvant %s apare de %i ori\n au fost
%i cifre”, a, numar_aparitii, numar_cifre);
free(a);}
23
Exemplu2 - stari
%{ char * a;
int nr_aparitii = 0, nr_cifre = 0;
%}
litera [A-Za-z]
cifra [0-9]
%x URMATOR
%%<INITIAL>{litera}+ { a = malloc(yyleng+1);
strcpy(a, yytext);
nr_aparitii = 1;
BEGIN (URMATOR); }
<URMATOR>{litera}+ {
if (!strcmp(a, yytext)) nr_aparitii++; }
<INITIAL URMATOR>{cifra} {numar_cifre++;}
%%
main()
{ yylex();
printf(„primul cuvant %s apare de %i ori\n au fost
%i cifre”, a, numar_aparitii, numar_cifre);
free(a);}
24
Stiva de stari
• %option stack
25
Exemplu – stiva de stari
%option stack
%x COMMENT
%%
"//" yy_push_state(COMMENT);
.|\n ;
<COMMENT>\n yy_pop_state();
<COMMENT>[^\n]+ printf("%s\n", yytext);
%%
int main ( int argc, char * argv[] )
{
yylex ();
return 0;
26
}
Determinarea potrivirilor in FLEX
%{
int n1 = 0, n2 = 0;
%}
%%
[a-c]+ {n1++;}
[a-d]+ {n2++;}
%%
main()
{
yylex();
printf(”n1 = %d, n2 = %d”, n1, n2);
}
27
REJECT
• Macroinstructiunea REJECT
28
Determinarea potrivirilor in FLEX
%{
int n1 = 0, n2 = 0;
%}
%%
[a-c]+ {n1++; REJECT}
[a-d]+ {n2++;}
%%
main()
{
yylex();
printf(”n1 = %d, n2 = %d”, n1, n2);
}
29
Alt exemplu REJECT
%%
„acesta” |
„acesta este” |
„acesta este un” |
„acesta este un test” |
„acesta este un test ciudat”
{ ECHO; REJECT;}
%%
main(){
yylex();
}
30
Alt exemplu REJECT
%%
„acesta” |
„acesta este” |
„acesta este un” |
„acesta este un test” |
„acesta este un test ciudat”
{ ECHO; REJECT;}
.
%%
main(){
yylex();
}
31
Exemplu 1 - REJECT
%{ int NrCuvinte = 0;
%}
cuvant [A-Za-z][A-Za-z0-9]*
%%
bun | rau | urit |frumos
{ ECHO; printf("adjectiv\n"); REJECT;}
{cuvant} { NrCuvinte++;}
. ;
%%
main ()
{ yylex();
printf("\n au fost %i cuvinte\n“, NrCuvinte);}
32
Exemplu 2 - REJECT
%{
int NrCuvinte = 0;
%}
cuvant [A-Za-z][A-Za-z0-9]*
%%
{cuvant} { NrCuvinte++; REJECT;}
bun | rau | urat |frumos
{ECHO; printf(" este adjectiv\n");}
main (){
yylex();
printf("\nau fost %i cuvinte\n", NrCuvinte);
}
33
yymore
0 1 yyleng-1
…
Sirul corespunzator
Wi potrivirii de la pasul i+1
intrare
0 1 yyleng-1
…
yytext
intrare
yyless(int n)
0 1 n-1 n yyleng-1
…
yyleng-n caractere
n caractere
intrare 36
Exemplu yyless, yymore
%s DUPA
Cuvint [A-Za-z]*
CuvintSpecial {Cuvint}"$"
CuvintObisnuit {Cuvint}[\t \n]+
%%
<INITIAL>"$" { BEGIN(DUPA); putchar('('); }
<INITIAL>{CuvintObisnuit} ;
<INITIAL>{CuvintSpecial} { yyless(yyleng - 1); }
<DUPA>"$" { BEGIN(INITIAL);
yytext[yyleng -1] =')';
ECHO;
}
<DUPA>{CuvintObisnuit} { yymore(); }
%%
Intrare:
main(){ a$a b$c
yylex(); a $a b$c
} aa$ a b$c
37
Analiza unui fisier de intrare
%{
…
%}
%%
…
%%
} 38
Fisiere de intrare multiple
int yywrap();
Valori intoarse:
1: nu mai exista fisiere de analizat la intrare
0: mai exista fisiere de analizat la intrare
39
Fisiere de intrare multiple
%{
#undef yywrap
…
%}
%%
…
%%
char **ListaFisiere;
unsigned int FisierCurent = 0;
unsigned int NumarFisiere;
fclose(yyin);
FisierCurent++;
/* afisare info specifice fisierului current */
41
Buffere de intrare multiple
YY_BUFFER_STATE yy_create_buffer
(FILE *file, int size)
void yy_switch_to_buffer
(YY_BUFFER_STATE new_buffer)
void yy_delete_buffer
(YY_BUFFER_STATE buffer)
void yypush_buffer_state
(YY_BUFFER_STATE buffer)
void yypop_buffer_state ( )
void yy_flush_buffer
(YY_BUFFER_STATE buffer)
42
Buffere de intrare multiple
/* buffer de intrare */
YY_BUFFER_STATE bp
FILE* f;
f = fopen(…, “r);
bp = yy_create_buffer(f, YY_BUF_SIZE);
yy_switch_to_buffer(bp);
….
….
yy_delete_buffer(bp);
43
Exemplu
%x incl
%%
include BEGIN(incl);
[a-z]+ ECHO;
[^a-z\n]*\n? ECHO;
<incl>[ \t]* ;
<incl>[^ \t\n]+ { /* preia nume fisier */
yyin = fopen( yytext, "r" );
if ( ! yyin ) error( ... );
yypush_buffer_state
(yy_create_buffer( yyin, YY_BUF_SIZE ));
BEGIN(INITIAL); }
<<EOF>> { yypop_buffer_state();
if ( !YY_CURRENT_BUFFER )
yyterminate(); 44
}