Documente Academic
Documente Profesional
Documente Cultură
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
=
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
=
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
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
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
>
autre
4
=
=
5 6
7
!
8 10
return(relop, ne)
Oprateurs de comparaison
Automates finis
chiffre
1 4
15
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
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
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
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
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).