Vous êtes sur la page 1sur 7

Institut Supérieur de Gestion de Tunis

Les Générateurs d’analyseurs lexicaux et syntaxiques


Elaboré par :
Sassi Najla najla_sassi@hotmail.fr

I. Générateurs d’analyseurs lexicaux


1. Définition
Le générateur d’analyseur lexical accepte en entrée des spécifications d’unités lexicales sous
forme de définitions régulières et produit un programme écrit dans un langage de haut niveau qui, une
fois compilé, reconnait ces unités lexicales.
Parmi ces générateurs nous pouvons citer : Lex(unix),Flex(windows)

2. Structure du fichier de spécifications (flex)


%{
Déclaration (en C) de variables, constantes,...
%}
Déclaration de définition régulières
%%
Règles de traduction
%%
Bloc principal et fonctions auxiliaires

 Une défintion reguliere permet d’asocier un nom à une expression réguliere et de se referer
par la Suite dans la section des règles à ce nom plutot qu’à l’expression réguliere.
 Les règles de traduction sont des suites d’instructions de la forme
Exp1 action1
Exp2 action2
Les exp sont des expression regulieres, les actions sont des bloc d’instruction en C si elle
comporte plusieurs instructions alors ils doivent etre entre {}.
 La derniere section est facultative.

3. Variables et fonctions prédéfinies 


Char yytext[] : tableau de caracteres qui contient la chaine d’entrée
Int yyleng : longueure de chaine
Int yylex() : fonction qui lance l’analyseur
Int main() par dfaut contient juste un appel à yylex(). L’utilisateur peut la redefinir dans la section des
fonctions auxiliaire.
4. Exemple de fichier.lex
Reconnait les nombres binaires
%%
(0|1)+ printf(« oh un nombre binaire !\n ») ;
Compte le nombre de voyelles, consonnes et caracteres de ponctuations d’un texte entré au clavier.
%{
Int nbvoy,nbcol,nbponct ;
%}
Consonne [b-df-hj-np-xz]
Ponctuation [, ;:?!\.]
Voyelle [aeiouy]
%%
Voyelle nbvoy++ ;
{consonne} nbconsonnes++ ;
{ponctuation} nbponct++ ;
%%
Main(){
Nbvoy=nbcons=nbponct=0 ;
Yylex() ;
Printf(‘il ya %d voyelles,%d consonnes et %d signes de ponctuation.\n »,nbvoy,nbcol,nbponct) ;
}

/* partie pour les déclarations de include et autres concernant tout ce que nous voudrions écrire
en C dans les actions sémantiques*/
%{
#include "global.h"
#include "compiler.h"
#include <stdlib.h>
%}
/* ici, vous spécifiez vos définitions régulières pour reconnaître des unités lexicales ou tokens*/
blancs [ \t]+
espace \040+
chiffre [0-9]
entier {chiffre}+
exposant [eE][+-]?{entier}
lettre [A-Za-z]
id {lettre}(_|({lettre}|{chiffre})*)
reel {entier}("."{entier})?{exposant}?
%% /*ici actions mises entre accolades à faire quand l’automate atteindra un état final*/
"while" {printf("UL reconnue : %s\n","WHILE");return(WHILE);};
{blancs} { /* On ignore */ }
{reel} {printf("UL reconnue : %s\n","NOMBRE");return(NOMBRE);};
{id} {printf("UL reconnue : %s\n","ID");return(ID);};
"{" {printf("UL reconnue : %s\n","ACCGAUCHE");return(ACCGAUCHE);};
"}" {printf("UL reconnue : %s\n","ACCDROITE");return(ACCDROITE);};
"+" {printf("UL reconnue : %s\n","PLUS");return(PLUS);};
"-" {printf("UL reconnue : %s\n","MOINS");return(MOINS);};
"*" {printf("UL reconnue : %s\n","FOIS");return(FOIS);};
"/" {printf("UL reconnue : %s\n","DIVISE");return(DIVISE);};
";" {printf("UL reconnue : %s\n","PV");return (PV);};
"^" {printf("UL reconnue : %s\n","PUISSANCE");return(PUISSANCE);};
"(" {printf("UL reconnue : %s\n","PARENTHESE_GAUCHE");return(PARENTHESE_GAUCHE);};
")" {printf("UL reconnue : %s\n","PARENTHESE_DROITE");return(PARENTHESE_DROITE);};
"=" {printf("UL reconnue : %s\n","AFFECTATION");return(AFFECTATION);};
"<" {printf("UL reconnue : %s\n","OPEREL");return(OPEREL);};
">" {printf("UL reconnue : %s\n","OPEREL");return(OPEREL);};
"<=" {printf("UL reconnue : %s\n","OPEREL");return(OPEREL);};
">=" {printf("UL reconnue : %s\n","OPEREL");return(OPEREL);};
"==" {printf("UL reconnue : %s\n","OPEREL");return(OPEREL);};
"<>" {printf("UL reconnue : %s\n","OPEREL");return(OPEREL);};
"\n" {printf("UL reconnue : %s\n","FIN");return(FIN);};
II. Générateurs d’analyseurs syntaxiques
1. Rappel

2. Définition
Un générateur d’analyseur syntaxique accepte en entrée la description d’un langage sous forme de
règles de productions et produit un programme écrit dans un langage de haut niveau qui, une fois
compilé, reconnait des phrases de ce langage.
Parmi ces générateurs nous pouvons citer : YACC (unix), BISON (windows)

3. Structure du fichier de spécifications (Bison)


%{
(1)Déclaration(en C) de variables, constantes...
%}
(2)Déclaration des unités lexicales utilisées
%%
(3)Règles de production avec éventuellement des actions sémantiques
%%
(4)Bloc principal(fonction main) et fonctions C supplémentaires

a. Les règles de production (la grammaire)


Non-terminal : prod1
| prod2
......
| prodn
;
Les symboles terminaux utilisables dans la description du langage sont
o Des unités lexicales que l’on doit impérativement déclarer (2) par %token nom
o Des caractères entre quotes
La partie (4) doit contenir une fonction yylex() effectuant l’analyse lexicale du texte, car l’analyseur
sémantique chaque fois qu’il a besoin du symbole terminal.

b. Actions sémantiques
Les actions sémantiques sont des instructions en C insérées dans les règles de production. Elles sont
exécutées chaque fois qu’il y a réduction par la production associée.
c. Variables, fonctions et actions prédéfinies

Int yyparse() : fonction qui lance l’analyseur syntaxique


YYACCEPT :instruction permettant de stopper l’analyseur syntaxique
Int main() contient par defaut un appel à yylex()
Exemples :
%%
Mot :S ‘$’{printf(« mot accepté ») ;YYACCEPT ;}
;
S :’a’ S ‘a’
|’b’ S ‘b’
| ‘c’
;
%%
Int yylex()
{
Char c=getchar();
If(c==’a’||c==’b’||c==’c’||c==’$’)return(c);
Else printf(“erreur: caractere non reconnu:%c »,c) ;
}

Spécification FLEX Spécification


*.lex BISON
*.y

FLEX BISON

YYLEX ( ) YYPARSE () main () +


Analyseur lexical Analyseur syntaxique actions+
Lex.yy.c y.tab.c *.c

Librairies
MinGW
CC

Programme
d. Exemple complet
La grammaire :

Programme  ListInst FIN


ListInst  Instruction PV ListInst | Instruction
Instruction  ID AFFECTATION Expression
G Expression  Expression + Terme | Terme
Terme  Terme * Facteur | Facteur
Facteur  ID | NB

Contenu Fichier compiler.y


%{

#include "global.h"
#include <stdio.h>
#include <stdlib.h>

%}
/* Ici, rappel des unités lexicales ou tokens générés par l’analyseur lexicale*/
%token NOMBRE
%token AFFECTATION
%token PLUS MOINS FOIS DIVISE PUISSANCE
%token PARENTHESE_GAUCHE PARENTHESE_DROITE
%token FIN
%token OPEREL
%token WHILE
%token ID
%token PV
%token ACCGAUCHE ACCDROITE
%left PLUS MOINS
%left FOIS DIVISE
%left NEG
%right PUISSANCE

%start Input
%%

Input:
Input Programme
| Programme
;
/* Ici, spécification de la grammaire*/
Programme:
ListInst FIN {printf("Analyses lexicales et syntaxiques réussies!\n");
printf("Tapez Enter pour terminer ou entrez une nouvelle chaine à analyser!\n");
} ;
ListInst:
Instruction PV ListInst
| Instruction
;
Instruction:
ID AFFECTATION Expression {}

;
Expression:

Expression PLUS Terme { }


| Terme {}
;
Terme:
Terme FOIS Facteur {}
| Facteur {}
;
Facteur:
NOMBRE {}
| ID { }
;
%%
int yyerror(char *s) {
printf("%s\n",s);
}
int main(void) {printf("Entrer la chaine des lexemes à analyser\n"); /* au départ, une action pour
demander de rentrer l’input constitué d’une suite de lexemes*/
yyparse();
}

Vous aimerez peut-être aussi