Sunteți pe pagina 1din 30

Analyse lexicale

Gnralits Expressions rationnelles Automates finis Analyseurs lexicaux

Rle d'un analyseur lexical


lexmes code source analyseur lexical table des symboles analyseur syntaxique ...

Sparer l'analyse lexicale de l'analyse syntaxique Rduire la complexit du compilateur et la complexit de conception de ces deux modules Augmenter la flexibilit du compilateur : portabilit, maintenabilit Augmenter l'efficacit du compilateur

Mthodes de construction
Utiliser un gnrateur d'analyseurs lexicaux (Flex) Ecrire l'analyseur lexical dans un langage volu

Lecture du code source (1/2)


On utilise un tampon de lecture cyclique en deux moitis Anticiper = lire quelques caractres d'avance pour dcider la valeur du lexme en cours ...

=
fin debut

4 * i + 1

...

Une anticipation de quelques caractres suffit Un langage o il n'y avait pas de limite la taille de l'anticipation : PL/1 DECLARE ( ARG1, ARG2, ... , ARGn ) Il faut attendre la fin de l'expression pour savoir si DECLARE est un motcl ou un nom de tableau

Lecture du code source (2/2)


...

=
fin debut

4 * i + 1

...

si fin atteint la fin de la premire moiti alors { charger la deuxime moiti fin := fin + 1 } sinon si fin atteint la fin de la deuxime moiti alors { charger la premire moiti fin := 0 } sinon fin := fin + 1

Mots et langages formels


Un mot sur un alphabet A est une suite finie de symboles pris dans A A peut tre l'ensemble des caractres, dans ce cas les lexmes sont des mots
code ASCII alphabet { 0, 1 } mots caractres

analyse lexicale
analyse syntaxique

caractres
lexmes

lexmes
programmes

Le mot vide est not , sa longueur est 0 Un langage formel est un ensemble de mots

Expressions rationnelles
On forme des expressions partir des symboles (lments de l'alphabet) et de en utilisant - l'union note | (ou +) - la concatnation (pas de symbole) - l'itration note *
On utilise souvent des oprations supplmentaires (abrviations) : + pour l'itration au moins une fois ? pour l'option . pour tout l'alphabet [...] pour une union de symboles

Priorits entre oprateurs : itration, concatnation, union

Expressions rationnelles
Identificateurs en C lettre = A | B | ... | Z | a | b | ... | z chiffre = 0 | 1 | ... | 9 id = (lettre | _) (lettre | _ | chiffre)* Nombres sans signe en C chiffre = 0 | 1 | ... | 9 chiffres = chiffre chiffre* frac = . chiffres exp = (E | e) (+ | - | ) chiffres | num = (chiffres (frac | . | ) | frac) exp Les mmes avec les abrviations chiffre = 0 | 1 | ... | 9 chiffres = chiffre+ frac = . chiffres exp = ((E | e) (+ | -) ? chiffres)? num = (chiffres (frac | .)? | frac) exp

Lexmes
Dfinition des espaces blancs delim = \b | \t | \n ws = delim* On dit habituellement lexme pour "catgorie de lexmes" : expression ws if else id num etc. lexme if else id num attribut pointeur valeur expression < <= == != > >= lexme relop relop relop relop relop relop attribut lt le eq ne gt ge

Automates finis
Les analyseurs lexicaux utilisent des graphes appels automates finis - les sommets sont appels tats - les transitions sont orientes et tiquetes - certains tats sont finaux et comportent une action

lettre | _ | chiffre

11

lettre _

12

autre

13

return(gettoken(), install)

Identificateurs en C

Automates finis
0
<

autre =

2 3

return(relop, lt) return(relop, le)

>

autre

4
=
=

5 6

return(relop, gt) return(relop, ge) return(relop, eq)

7
!

8 10

return(relop, ne)

Oprateurs de comparaison

Automates finis
chiffre

1 4

15
chiffre

chiffre E|e +|chiffre

16
chiffre . . E|e chiffre

17
chiffre

18

autre

19

20

chiffre

21

2 2

23
chiffre

autre

24
chiffre .

25

chiffre

26

autre

Nombres sans signe en C

Implmentation en C
Un programme C qui reconnat dans le dbut d'une chane de caractres un des lexmes dfinis par les automates /* Recherche de l'tat initial du prochain automate */ int state = 0, start = 0 ; int lexical_value ; int fail() { forward = token_debut ; switch(start) { case 0 : start = 11 ; break ; case 11 : start = 14 ; break ; case 14 : start = 22 ; break ; case 22 : recover() ; break ; default : /* erreur */ } return start ; }

token nexttoken() { while (1) { switch(state) { case 0 : c = nextchar() ; if (c==blank||c==tab||c==newline) { state = 0 ; debut ++ ; } else if (c == '<') state = 1 ; else if (c == '>') state = 4 ; else if (c == '=') state = 7 ; else if (c == '!') state = 9 ; else state = fail() ; break ; /* ... cas 1 - 10 ... */ case 11 : c = nextchar() ; if (isletter(c)||c=='_') state = 12 ; else state = fail() ; break ;

case 12 : c = nextchar() ; if (isletter(c)||c=='_') state = 12 ; else if (isdigit(c)) state = 12 ; else state = 13 ; break ; case 13 : retract(1) ; install_id() ; return(gettoken()) ; /* ... cas 14-26 ... */ } }
}

Automates dterministes
Un automate fini est dterministe si : - il possde au plus un tat initial - de chaque tat part au plus une flche tiquete par un symbole donn Exemple d'automate non dterministe :
a|b

1
a

Exemple d'automate dterministe :


b a a

1
b

Automates dterministes
Un automate dterministe reprsentant un ensemble de mots peut tre utilis commodment pour reconnatre l'un des mots dans une chane de caractres : il suffit de partir de l'tat initial, de suivre les flches et de voir si l'tat dans lequel on arrive est final. Tout automate fini est quivalent un automate fini dterministe : il existe un automate fini dterministe qui reconnat le mme langage.

Dterminisation
Algorithme : on part d'un automate fini A = (Q, I, F, ). On construit l'automate dterministe D ayant 1. comme tats les parties de Q 2. comme tat initial I 3. comme tats finaux les parties de Q contenant au moins un lment de F 4. comme transitions les (U, a, V) si V est l'ensemble des tats atteignables depuis U par une transition tiquete a Complexit : si A a n tats, D a au plus 2n tats.

Exemple
a|b

Un automate non dterministe

a a b

12
a

13

Le rsultat de l'algorithme

Gnralisation
On peut admettre des transitions d'tiquette (transitions spontanes). Pour tre dterministe, un automate ne doit pas contenir de transitions spontanes. Pour dterminiser, on adapte l'algorithme prcdent : - l'tape 2 on prend l'ensemble des tats atteignables depuis I par un chemin de transitions spontanes ; - l'tape 3, V est l'ensemble des tats atteignables depuis U par un chemin tiquet a

La construction rcursive
On peut construire un automate fini quivalent une expression rationnelle : il reconnat le mme langage. L'automate construit est tel que : - il a un seul tat initial i - il a un seul tat final f i - aucune transition n'entre dans i - aucune transition ne sort de f. Pour et a, on prend:

union

concatnation

itration

Utilisation de Flex
spcification Flex flex lex.yy.c compilateur C

caractres (code source)

a.out

lexmes

...

4 tapes : - crer sous diteur une spcification Flex (expressions rationnelles) - traiter cette spcification par la commande flex - compiler le programme source C obtenu - excuter le programme excutable obtenu

Spcifications Flex
Un programme Flex est fait de trois parties : dclarations %% rgles de traduction %% fonctions auxiliaires en C Les rgles de traduction sont de la forme p1 { action1 } p2 { action2 } ... pn { actionn } o chaque pi est une expression rationnelle et chaque action une suite d'instructions en C.

Exemple
%{ /* Partie en langage C : dfinitions de constantes, dclarations de variables globales, commentaires... */ %} delim [ \t\n] letter [a-zA-Z] %% {delim}* { /* pas d'action */ } if { return IF ; } then { return THEN ; } else { return ELSE ; } {letter}({letter}|[0-9])* { yyval = install_id() ; return ID ; } ([0-9]+(\.[0-9]*)?|\.[0-9]+)((E|e)(\+|-)?[0-9]+)? { yyval = install_num() ; return NUMBER ; }

Exemple
"<" { yyval = LT ; return RELOP ; } "<=" { yyval = LE ; return RELOP ; } %% install_id() { /* fonction installant dans la table des symboles le lexme vers lequel pointe yytext et dont la longueur est yylength. Renvoie un pointeur sur l'entre dans la table */ } install_num() { /* fonction calculant la valeur du lexme */ }

Spcifications Flex
Les commentaires /* ... */ ne peuvent tre insrs que dans une portion en C : - dans la partie dclaration, seulement entre %{ et %} ; - dans la partie rgles, seulement dans les actions ; - dans la partie fonctions auxiliaires, n'importe o. Dans les rgles pi { actioni } les expressions rationnelles pi ne peuvent pas contenir d'espaces blancs (ou alors d-spcialiss). Dans la partie rgles, si une rgle commence par un espace blanc, elle est interprte comme du langage C et est insre dans lex.yy.c au dbut de la fonction qui renvoie le prochain lexme (utilisable pour dclarer des variables locales).

Segmentation du code source par l'analyseur lexical (1/3)


L'analyseur lexical produit par Flex - commence chercher les lexmes au dbut du code source ; - aprs chaque lexme reconnu, recommence chercher les lexmes juste aprs Exemple : si pirat est reconnu, rat n'est pas reconnu Si aucun lexme n'est reconnu partir d'un point du code source l'analyseur affiche le premier caractre sur la sortie standard et recommence chercher partir du caractre suivant

Segmentation du code source par l'analyseur lexical (2/3)


Si plusieurs lexmes sont reconnus partir d'un point du code source (conflit) 1. Deux lexmes de longueurs diffrentes C'est le plus long qui gagne Exemple : [a-zA-Z_] [a-zA-Z_0-9]*

Segmentation du code source par l'analyseur lexical (3/3)


2. Deux lexmes de mme longueur Ils commencent au mme point et terminent au mme point : s'il y a conflit, c'est qu'ils sont issus de deux rgles diffrentes. C'est la rgle qui apparat la premire dans la spcification Flex qui gagne Exemple : conflit entre [a-zA-Z_] [a-zA-Z_0-9]* et while Mettre l'exception avant la rgle En dehors de ce cas, l'ordre des rgles ne joue pas

S-ar putea să vă placă și