TP de Compilation : une solution de l'exercice 1 du TP 1
1.1.
Certes, on n'utilise pas Lex pour une analyse lexicale trop simple
ou quand la compacité du code source (et éventuellement de
l'exécutable) est une contrainte du projet.
Mais vous sentez-vous capable d'écrire à la main un code aussi
efficace et rapide pour n'importe quel analyseur ?
1.2.
Cet analyseur reconnait les voyelles :
- Le motif
[aeiou]
correspond à l'expression
rationnelle ('a'+'e'+'i'+'o'+'u') ; l'action qui lui est
associée printf("!"); affiche un point d'exclamation.
- Le motif
.|\n
correspond à la reconnaissance de
tout autre caractère (.) que ce qui peut être inclus dans une règle
précédente ou (|) d'un retour à la ligne Unix (\n) ;
l'action associée est l'affichage du motif reconnu car la commande
ECHO
peut être définie comme
printf("%s",yytext)
où yytext
est la
variable chaine qui contient le motif reconnu.
En conclusion, cet analyseur remplace toutes les voyelles d'un texte
par un point d'exclamation, et laisse les autres caractères du flux
d'entrée inchangés.
Remarques :
- Il était inutile de préciser l'action
ECHO
associée au second motif car cette action est associée par défaut à
tout motif dépourvu d'action associé ou non-reconnu par une règle
du fichier-lex.
- Ne pas oublier de séparer l'expression et son code associé par
un ou plusieurs espaces (ou tabulations).
1.3.
La ligne .|\n
est inutile, selon le principe que
"tout ce qui n'est pas digéré sort tel qu'il est entré".
1.4.
Quand on tape le mot FIN
seul sur une ligne, l'analyseur
s'arrete :
l'instruction return 0;
est inséré dans le code de la fonction
yylex()
qui se termine alors et termine le
programme puisque, par défaut, le bloc principal du programme est
défini par : main(){yylex();}
1.5.
Dans ce cas l'analyseur, avant de s'arrêter, affiche :
premiere fin
En effet, si un fichier-lex contient deux motifs équivalents, seul
le premier motif sera utilisé.
Questions supplémentaires
Que se passe-t-il si on modifie de la manière suivante la première ligne
rajoutée ?
^FIN$
{printf("premier \n"); REJECT; return 0;}
Rappel : l'instruction REJECT
a pour effet de
remettre le motif reconnu dans le flux d'entrée au lieu de le
"consommer".
Que se passe-t-il si on remplace les deux lignes rajoutées par les
quatres lignes suivantes ?
^FIN
{printf("premier \n"); return 0;}
^FINI
{printf("deuxieme \n"); return 0;}
^FINIR
{printf("troisieme \n"); REJECT; return 0;}
^FINIS
{printf("quatrieme \n"); return 0;}
N.B. Le comportement de ce code ne sera pas forcément le même selon
qu'on utilise Lex ou Flex.
1.6.
Si vous n'avez pas trouvé, regardez la suite du TP...
© 2000, 2017 – A. Sigayret