TP de compilation : une solution de l'exercice 3 du TP 1
3.1.
On doit rechercher le motif [ \t]+
dans divers situations :
–
en fin de ligne pour éliminer les espaces et tabulations superflues,
–
en début de ligne pour conserver une unique tabulation,
–
dans les autres circonstances pour ne conserver qu'un espace séparateur.
La difficulté de l'exercice est de faire distinguer à Lex ces
différentes situations. Il faut pour cela ordonner les motifs des plus
spécifiques aux plus généraux.
Une solution peut être :
SP [ \t]+
%%
^\n {return 0;}
^{SP}$ ;
{SP}$ ;
^{SP} {printf("\t");}
{SP} {printf(" ");}
N.B. Il n'est pas toujours facile de tester ce programme avec des
espacements, on pourrait remplacer par exemple le motif
[ \t]+
par [et]+
le temps de tester le
comportement de l'analyseur.
On peut aussi remarquer que la première ligne d'analyse est
redondante :
^{SP}$
semble subsumée par
{SP}$ ;
peut-on retirer sans soucis cette ligne ?
(le comportement peut être différent avec Flex d'avec Lex)
L'espace étant un méta-caractère de Lex, son utilisation comme
caractère à reconnaître peut se faire entre crochets [ ]
,
entre guillements " "
, ou entre apostrophes
' '
.
On peut maintenant réaliser le décompte des mots du texte.
Plusieurs solutions existent.
Proposons deux solutions (quels sont les avantages et
inconvénients de chacune ?).
%{
// Solution 1
int c=1;
%}
SP [ \t]+
%%
^\n {return 0;}
^{SP}$ {c=0;}
{SP}$ ;
^{SP} {printf("\t");}
{SP} {printf(" ");c++;}
\n
{printf(" : %d mot(s) sur la ligne\n",c); c=1;}
%{
// Solution 2
int c=0;
%}
SP [ \t]+
%%
^\n {return 0;}
^{SP}$ ;
{SP}$ ;
^{SP} {printf("\t");}
{SP} {printf(" ");}
[a-zA-Z]+ {ECHO; c++;}
\n
{printf(": %d mot(s) sur la ligne\n",c); c=0;}
3.2.
Un seule règle devrait suffire :
^[a-z] {printf("%c",yytext[0]-32);}
3.3.
On peut, par exemple, ajouter en premier motif dans le premier
analyseur la règle du second analyseur.
Mais pourquoi ne pas tout simplement mettre les deux analyseurs en
série ? Si analyseur1
et analyseur2
sont les
exécutables de ces deux analyseurs, essayer la commande shell :
analyseur1|analyseur2
.
© 2000, 2017 – A. Sigayret