Vous êtes sur la page 1sur 11

Institut Supérieur Section : L_INFO_2

Enseignante : Aida Lahouij


d'Informatique et de
Matière : Techniques de
Mathématiques de Monastir Compilation
2022/2023

Correction TD2
Analyse lexicale automatique
Exercice1:
1. Ecrire un programme Flex qui copie un programme écrit en C et qui remplace le mot
clé float par double.
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
%}
flt "float"
%%
{flt} {printf("double");}
%%
int main (int args,char *argr[]){
FILE *f;
if(args>1){
f=fopen(argr[1] , "r") ;
if(!f){
printf("fichier n est existe pas") ;
exit(1) ;
}
else{
yyin=f;
yylex();
fclose(f);
}
}
return 0 ;
}

2. Ecrire un programme Flex qui permet de compter le nombre de lignes, de mots et de


caractères d’un fichier en entrée. Le programme affichera ensuite ces nombres.
%{
unsigned charCount=0,wordCount=0,lineCount=0;
%}
word [^ \t\n]+
eol \n
%%
{word} {wordCount++;charCount+=yyleng;}
{eol} {charCount++;lineCount++;}
. charCount++;
%%
int main(int argc,char *argv[])
{
if(argc>1){
FILE *file;
file = fopen(argv[1],"r");
if(!file){
fprintf(stderr,"fichier ne peut être ouvert%s\n",argv[1]);
exit(1);
}
yyin=file;
}
yylex();
printf("%d %d %d\n",lineCount,wordCount,charCount);
return 0;
}

3. Ecrire un programme Flex qui numérote les lignes d’un fichier (hormis les lignes
blanches)
%{
int yywrap (void) {} /* GNU flex */
int Nb_Line = 1;
%}
blanc " "|\t
%%
^({blanc})* {}
\n {}
^.* {printf("[%d] %s\n",Nb_Line, yytext); Nb_Line++;}
%%
#include <stdio.h>
int main () {
yylex();
return 0;
}
4. Ecrire un programme Flex qui n’imprime que les commentaires d’un programme. Ceux-
ci sont compris entre {}.
%{
int yywrap (void) {}
%}
%%
"{"([^{}])+"}" {ECHO;}
.|\n {}
%%
#include <stdio.h>
int main () {
yylex();
return 0;
}
5. Ecrire un programme Flex qui transforme un texte en remplaçant le mot compilateur
par interp si la ligne début par a, par binterp si la ligne débute par b et par cinterp ! si la
ligne débute par c.
%{
int yywrap (void) {} /* GNU flex */
int i;
%}
%%
\n {ECHO; i = 0;}
^a {ECHO; i = 1;}
^b {ECHO; i = 2;}
^c {ECHO; i = 3;}
compilateur {if (i == 1) printf("interp");
if (i == 2) printf("binterp");
if (i == 3) printf("cinterp!");
if (i == 0) printf("compilateur");}
. {ECHO;}
%%
#include <stdio.h>
int main () {
i = 0;
yylex();
return 0;
}
6. Ecrire un programme en Flex qui supprime une suite d’espaces et les remplace par un
seul espace.
%{
#include<stdio.h>
%}
espace [ \t]
%%
({espace})+ {printf(" ");}
%%
int main (int args,char *argr[]){
FILE *f;
if(args>1){
f=fopen(argr[1] , "r") ;
if(!f){
printf("fichier n est existe pas") ;
exit(1) ;
}
else{
yyin=f;
yylex();
fclose(f) ;
}}
return 0 ;
}
7. Ecrire un programme en Flex qui convertit une chaine en majuscule si elle est
minuscules et inversement.
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
%}
Min [a-z]
Maj [A-Z]
Espas [ \t\n]
%%
{Min} {printf("%c",yytext[0]-32);}
{Maj} {printf("%c",yytext[0]+32);}
{Espas} { ECHO ;}
%%
int main (int args,char *argr[]){
FILE *f;
if(args>1){
f=fopen(argr[1] , "r") ;
if(!f){
printf("fichier n est existe pas") ;
exit(1) ;
}
else{
yyin=f;
yylex();
fclose(f) ;
}}
return 0 ;
}

Exercice2:
Le tableau suivant énumère les expressions régulières de base utilisées en Lex :

En utilisant les expressions ci-dessous :

1. Ecrire un programme Flex qui reconnait une adresse électronique simple.


%{
#include<stdio.h>
%}
mot [a-zA-Z]+
digit [0-9]*
%%
{mot}{digit}@{mot}.{mot} {printf("%s\n",yytext);}
.|\n {}
%%
int main (int argc, char *argv[]){
FILE *f;
if(argc>1){
f=fopen(argv[1] , "r");
if(!f){
printf("fichier n est existe pas\n") ;
exit(1) ;
}
else{
yyin=f;
yylex();
fclose(f) ;
}}
return 0 ;
}

2. Ecrire un programme Flex qui reconnait les commentaires en langage C.


%{
#include<stdio.h>
%}
%%
"/*"([^//])+"*/" {ECHO; printf("\n");}
"//".* {ECHO; printf("\n");}
.|\n {}
%%
int main (int argc,char *argv[]){
FILE *f;
if(argc>1){
f=fopen(argv[1] , "r") ;
if(!f){
printf("fichier n est existe pas\n");
exit(1) ;
}
else{
yyin=f;
yylex();
fclose(f) ;
}}
return 0 ;
}
3. Ecrire un programme Flex qui reconnait les chaines contenant un nombre pair de a.
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int i,j=0;
%}
%%
[a-zA-Z]+ { j=0;
for(i=0;i<yyleng;i++) if(yytext[i]=='a') j+
+;
if(j%2==0) printf("%s\n",yytext);
}
.|\n {}
%%
int main(int argc,char *argv[])
{
if(argc>1)
{
FILE *file=fopen(argv[1],"r");
if(!file)
{
printf("Ce fichier n'existe pas\n"); exit(-1);
}
yyin=file;
yylex();
fclose(file);
}
return 0;
}
4. Ecrire un programme Flex qui reconnait les chaines ne contenant pas les caractères x
jusqu’à z.
%{
#include<stdio.h>
int i,j;
%}
%%
[a-zA-Z]+ { j=0;
for(i=0;i<yyleng;i++)
{
if(yytext[i]=='x' ||yytext[i]=='y' ||
yytext[i]=='z') j++;
}
if(j==0) printf("%s\n",yytext);
}
.|\n {}
%%
int main(int argc,char *argv[])
{
if(argc>1)
{
FILE *file=fopen(argv[1],"r");
if(!file)
{
printf("Ce fichier n'existe pas\n"); exit(-1);
}
yyin=file;
yylex();
fclose(file);
}
return 0;
}
5. Ecrire un programme Flex qui reconnait les chaines commençant par les lettres acc.
%{
#include<stdio.h>
%}
%%
acc[a-zA-Z]* { printf("%s\n",yytext);}
.|\n {;}
%%
int main(int argc,char *argv[])
{
if(argc>1)
{
FILE *file=fopen(argv[1],"r");
if(!file)
{
printf("Ce fichier n'existe pas\n"); exit(-1);
}
yyin=file;
yylex();
fclose(file);
}
acc mml
return 0;
}

Exercice 3:
On veut concevoir un langage pour manipuler des expressions. Pour cela, on définit des
constantes entières val, des noms de variables ident, les parenthèses, les opérateurs +, -, *, /, :=,
et un marqueur de fin d’expression ;.

À l’aide de lex, générez un programme pour reconnaître ces lexèmes.

%{

#include <stdio.h>

#include <stdlib.h>

#define TOKEN_EOF 0

#define TOKEN_VAL 1
#define TOKEN_VAR 2

#define TOKEN_PLUS 3

#define TOKEN_MOINS 4

#define TOKEN_MUL 5

#define TOKEN_DIV 6

#define TOKEN_AFFECT 8

#define TOKEN_FIN 9

#define TOKEN_LPAR 10

#define TOKEN_RPAR 11

%}

C [0-9]

L [A-Za-z]

%%

"+" return TOKEN_PLUS ;

"-" return TOKEN_MOINS ;

"*" return TOKEN_MUL ;

"/" return TOKEN_DIV ;

":=" return TOKEN_AFFECT ;

";" return TOKEN_FIN ;

"(" return TOKEN_LPAR ;

")" return TOKEN_RPAR ;

{C}+ return TOKEN_VAL ;

{L}({L}|{C})* return TOKEN_VAR ;

[ \t\n] ;

. { fprintf (stderr, "erreur lexicale %s à la ligne %d.\n", yytext[0], yylineno); }

%%

int main(){

int token_courant;

printf("Codes des tokens retournés par yylex: ")

do {
token_courant=yylex();

printf("%d ", token_courant);

token_courant=yylex();

} while (token_courant !=TOKEN_EOF);

return(0)

Vous aimerez peut-être aussi