Analyse lexicale
Le scanner a pour rôle principal de préparer le travail pour les phases d'analyses syntaxico-sémantiques.
L'analyse lexicale est une analyse microscopique des éléments formant un programme.
Ces éléments sont appelés "unités lexicales".
Comme unités lexicales on peut avoir
les mots réservés du langage : Debut, Tq, Finsi, ...
les identificateurs utilisateurs
les caractères spéciaux
les constantes
Etc.
Un analyseur lexical ( ou scanner ) élimine tout ce qui n'est pas utile pour la phase suivante qui estl'analyse syntaxique. Il ignore les commentaires et les blancs.
L'analyseur lexical transforme le texte source en un ensemble de couples (Sem, Syn) utilisés par les prochaines phases de compilation.
Sem : c'est l'unité lexicale elle-même
Syn : c'est le code associé à l'unité.
Syn est utilisée par l'analyseur syntaxique, Sem est utilisée par l'analyseur sémantique.
Les codes (Syn) sont répartis en classes.
Les éléments d'une classe jouent le même rôle pour l'analyse syntaxique. Ainsi, tous les identificateurs ont le même code.
Unités lexicales produites
Idf : Identificateur
Listecste : liste de constantes numériques séparées par des ,
Exp :expression
Chaine : chaine de caractères
Expchaine : expression chaine de caractères
Listexp : liste d'expressions séparées par des ,
===================================
* Syn | Sem *
===================================
* 1 | Identificateur *
-----------------------------------
* 2 | Booleen *
* 2 | Booleens *
* 2 | Entier *
* 2 | Entiers *
* 2 | Caractere *
* 2 | Caracteres *
* 2 | Car *
* 2 | Chaine *
* 2 | Chaines *
* 2 | Machine_car *
* 2 | Machine_c *
* 2 | Machine_nombre *
* 2 | Machine_N *
-----------------------------------
* 3 | ^ *
* 3 | Non *
-----------------------------------
* 4 | * *
* 4 | / *
* 4 | Et & *
-----------------------------------
* 5 | + *
* 5 | - *
* 5 | Ou ! *
-----------------------------------
* 6 | > *
* 6 | >= *
* 6 | < *
* 6 | <= *
* 6 | = *
* 6 | <> *
* 6 | # *
* 6 | ^= *
-----------------------------------
* 7 | ( *
-----------------------------------
* 8 | ) *
-----------------------------------
* 37 | [ *
-----------------------------------
* 38 | ] *
-----------------------------------
* 9 | , *
-----------------------------------
* 10 | : *
-----------------------------------
* 11 | ; *
-----------------------------------
* 12 | . *
-----------------------------------
* 13 | := *
-----------------------------------
* 14 | Vrai *
* 14 | Faux *
-----------------------------------
* 15 | Tantque *
* 15 | Tq *
-----------------------------------
* 16 | Ftq *
* 16 | Fintantque *
-----------------------------------
* 17 | Si *
-----------------------------------
* 18 | NIL *
* 19 | Ecrire *
-----------------------------------
* 20 | Lire *
-----------------------------------
* 21 | Sinon *
-----------------------------------
* 22 | Cste Numerique*
-----------------------------------
* 23 | Soit *
* 23 | Soient *
-----------------------------------
* 24 | Finsi *
* 24 | Fsi *
-----------------------------------
* 25 | Cste Chaine *
*---------------------------------*
* 26 | Allouer * ( Exp )
* 26 | Liberer *
* 26 | Fermer *
-----------------------------------
* 27 | Suivant * ( Exp )
* 27 | Longchaine *
* 27 | aleachaine *
* 27 | aleanombre *
----------------------------------*
* 28 | Lirecar * ( Idf, Idf )
* 28 | Lirenombre *
* 28 | Lireseq *
* 28 | Ecrireseq *
* 28 | Demandbloc *
* 28 | Rajouter *
----------------------------------*
* 29 | NbrCar * ( Idf )
* 29 | NbrNombre *
* 29 | Finfich *
* 29 | Alloc_bloc *
----------------------------------*
* 30 | Aff_struct * (Exp, Exp, Exp)
* 30 | Aff_entete *
* 30 | LIREDIR *
* 30 | ECRIREDIR *
----------------------------------*
* 31 | Aff_element * ( Idf, [ <Listexp> ] , Exp )
-----------------------------------
* 33 | Element * (Exp [ <Listexp> ] )
-----------------------------------
* 34 | Struct * (Exp, Exp)
* 34 | Entete * (Exp, Exp)
* 34 | Caract * (Exp, Exp)
-----------------------------------
* 35 | Creer_Mcar * ( Idf, [ Chaine ] )
*---------------------------------*
* 36 | Vecteur(s) * ( <Listecste> )
* 36 | Tableau(x) * ( <Listecste> )
-----------------------------------
* 39 | Creer_liste * ( Idf, [ <Listexp> ] )
* 39 | init_vecteur *
* 39 | init_tableau *
* 39 | init_struct *
* 39 | Creer_MNombre *
*---------------------------------*
* 40 | Un *
* 40 | Une *
* 40 | Des *
*---------------------------------*
* 41 | Debut *
-----------------------------------
* 42 | Fin *
-----------------------------------
* 43 | De *
-----------------------------------
* 44 | Liste(s) *
-----------------------------------
* 45 | Vers *
-----------------------------------
* 46 | Pointeurs *
-----------------------------------
* 47 | Pour *
-----------------------------------
* 48 | Finpour *
* 48 | Fpour *
*---------------------------------*
* 49 | Structure *
-----------------------------------
* 50 | Aff_adr * (Exp, Exp)
* 50 | Aff_val *
-----------------------------------
* 51 | Appel *
-----------------------------------
* 52 | Action *
-----------------------------------
* 53 | Fonction *
-----------------------------------
* 54 | Fichier *
-----------------------------------
* 55 | Buffer *
-----------------------------------
* 56 | Ouvrir * (Idf, Expchaine, Expchaine)
===================================
Entete figure aussi dans une déclaration de fichier.
Les commentaires sont compris entre les symboles /* et */ ou { et }
Fragment de l'analyseur lexical
Les règles de grammaire permettant la formation des unités lexicales sont régulières. Aussi, le scanner est écrit sous forme d'un automate.
Voici un fragment de notre analyseur
CASE Cl OF
1: { Le caractère lu est un chiffre }
BEGIN
Nombre ; Syn :=22 ; Sem := A;
END;
2: { Le caractère lu est une lettre alphabétique
Il s'agit d'un idf ou d'un mot réservé }
BEGIN
WHILE ( Cl <=2) DO
BEGIN
Longidf := Longidf + 1 ;
IF Longidf < Maxlongidf THEN A := A + Ch ;
Nextch;
END;
IF Longidf >= Maxlongidf THEN Erreur(1);
Syn := 1 ;
Sem := A ;
{ Test Fin De Fichier }
IF Sem ='$'
THEN Syn := 0
ELSE
BEGIN
{ Est-ce un mot réservé?}
Estmores (J) ;
IF J <> 0 THEN Syn := Coderes[J];
END
END;
3: { C'est un délimiteur simple }
BEGIN
A := A + Ch ;
Syn := Coddlm [Pos(Ch, Dlm)];
Sem := A;
Nextch;
END;
4: { Le caractŠre lu est un / ou '{' }
IF Ch = '{'
THEN
BEGIN
Nextch;
WHILE (Ch <> '}') AND (Ch <> '$') DO
Nextch;
IF Ch = '$' THEN Erreur(4)
ELSE
BEGIN
Nextch;
GOTO Debut
END
END
ELSE
BEGIN
A := A + Ch;
Nextch;
IF Ch ='*'
THEN { Il s'agit d'un commentaire}
BEGIN
Et1 : Nextch;
IF Ch='$' THEN Erreur(4);
Et2 :IF Ch <> '*'
THEN GOTO Et1
ELSE
BEGIN
Nextch;
IF Ch='$' THEN Erreur(4);
IF Ch <> '/'
THEN GOTO Et2
ELSE
BEGIN
Nextch ;
GOTO Debut ;
END ;
END;
END
ELSE { Ch <> '*' }
{ Il s'agit du délimiteur simple'/'}
BEGIN
Syn := 4 ;
Sem :=A ;
END;
END;
5: .....