"ExoGram" : Exercices de Grammaire Corrigé



0. Sommaire
Partie 1 : Automates finis
Partie 2 : Hiérarchie des langages
   2.1 Exemple simple
   2.2 Langage régulier
   2.3 Langage am bncp
   2.4 Palindromes
   2.5 Langage an bn
   2.6 Grammaire ambiguë
   2.7 Langage an bn cn
   2.8 an bn cp et an bp cp
   2.9 an bp cn dp
Partie 3 : Analyse syntaxique LR
   3.1 Analyse shift/reduce
   3.2 Récursivité gauche/droite
   3.2bis Analyse "Ligne à ligne"
   3.3 Suppression de conflits
   3.4 Grammaire ambiguë
   3.5 Conflit reduce/reduce

0. Sommaire et Objectifs

Ces exercices complètent directement les slides du cours et illustrent plus particulièrement les aspects théorie des langages à travers des exemples classiques.


Partie 1 : Automates finis

(pas d'énoncé, pas de corrigé!)

On se donne en figures jointes quelques illustrations d'automates finis. Il s'agit d'analyser ces automates, de décrire de façon informelle le langage reconnu, éventuellement de déterminer une expression régulière équivalente....


Partie 2 : Hiérarchie des langages

2.1 Exemple simple

Écrire une grammaire générant le langage représenté par l'expression régulière a*b . Quel est le type de cette grammaire ?

Corrigé :

R1  S → aS
R2  S → b
Une autre solution avec une grammaire linéaire gauche :
R1  S → Tb
R2  T → Ta
R3  T → ε

2.2 Langage régulier

Soit la grammaire G1 :

R1  S → aSa
R2  S → aa
R3  S → a

Corrigé

Conclusion:

2.3 Langage am bncp

Écrire une grammaire générant le langage L = {am bn c p | m,n,p >= 1}.

Si possible utiliser une grammaire linéaire droite ou gauche.

Corrigé

R1  S → aS
R2  S → aB
R3  B → bB
R4  B → bC
R5  C → cC
R6  C → c

Le langage est régulier, reconnu par l'expression régulière a+b+c+.
La grammaire est ici une grammaire régulière, linéaire à droite.

On peut aussi avoir la forme linéaire gauche suivante :

R1  S → Sc
R2  S → Bc
R3  B → Bb
R4  B → Ab
R5  A → Aa
R6  A → a

2.4 Palindromes

Soit un alphabet A = {a,b,c,d}, écrire une grammaire générant le langage L = {wdw, w dans {a,b,c}* et w la chaîne miroir de w}

Quel est le type de ce langage et de cette grammaire ?

Corrigé :

R1  S → aSa
R2  S → bSb
R3  S → cSc
R4  S → d

Cette grammaire est context-free, linéaire mais non régulière. La théorie des langages montre que ce langage est algébrique non régulier. Il ne peut donc pas être décrit par une expression régulière ou par un grammaire régulière.

2.5 Langage an bn

Écrire une grammaire générant le langage L = {an bn | n > 0} .

Quel est le type de ce langage et de cette grammaire ?

Corrigé

R1  S → aSb
R2  S → ab

Le langage est algébrique non régulier, la grammaire est context-free, linéaire ni droite ni gauche, et non régulière.

2.6 Grammaire ambiguë

Montrer que la grammaire d'opérateurs suivante est ambiguë.

R1 E → E + E
R2 E → E - E
R3 E → E * E
R4 E → E / E
R5 E → ( E )
R6 E → a | b | c

Peut-on faire une grammaire non ambiguë pour le même langage ?

Corrigé La grammaire est ambiguë si il existe 2 arbres de dérivation possibles pour une même expression.

par exemple, la chaîne  a + b * c  correspond à 2 arbres corrects

     R1                R3
    /  \              / \
  R6   R3            R1  R6
  |    / \          / \   |
  a   R6  R6       R6 R6  c
      |   |        |   |
      b   c        a   b

On peut trouver une grammaire non ambiguë pour le même langage, en rajoutant des symboles non-terminaux. "Une Expression est une somme de Termes qui sont des produits de Facteur".

E → E + T | E - T | T
T → T * F | T / F | F
F → ( E ) | a | b | c

2.7 Langage an bn cn

Le langage L = {an bn cn| n > 0} est non algébrique (ou dépendant du contexte, ou context-sensitive), c'est-à-dire qu'il n'existe pas de grammaire context-free permettant de générer ce langage.

Ce langage est engendré par la grammaire suivante :

R1   S → aBSc
R2   S → aBc
R3   Ba → aB
R4   Bc → bc
R5   Bb → bb

Donner les pas de dérivation nécessaires pour reconnaître les chaînes "abc", puis "aabbcc", puis "aaabbbccc".

Corrigé

2.8 an bn cp et an bp cp

Considérons les deux langages :

Quelle est la nature des langages : L1 , L2 , L1 ∩ L2 et L1 ∪ L2 ?

Corrigé:

2.9 an bp cn dp

Les langages suivants sont-ils algébriques ou pas ?

Suggestion : On peut aussi analyser la question en terme d'automates à pile plutôt que de grammaire context-free.

Corrigé:
L2 et L3 sont algébriques, et facilement reconnaissables avec une Pile.
L1 n'est pas algébrique (...lemme d'Ogden...).

Conséquence pratique : Vérifier l'égalité du nombre d'arguments entre la déclaration d'une fonction et son utilisation ne peut pas être fait de façon systématique par l'utilisation de grammaires context-free.


Partie 3 : Analyse syntaxique LR

3.1 Analyse ascendante avec décalage/réduction

Écrire les décalages/réductions nécessaires pour reconnaître le fragment ababa avec la grammaire suivante :

R1  S → AB 
R2  A → ab 
R3  B → aba

Corrigé :

paschaîne d'entréelisteaction
0•ababaDécalage
1a•babaaDécalage
2ab•abaabReduc : R2
3ab•abaADécalage
4aba•baAaDécalage
5abab•aAabDécalage
6ababa•AabaReduc : R3
7ababa•ABReduc : R1
8ababa•Ssuccès

3.2 Récursivité à gauche ou à droite

Écrire les décalages/réductions nécessaires pour reconnaître le fragment aaaa avec la grammaire récursive gauche :

R1  S → Sa
R2  S → a

Corrigé

paschaîne d'entréelisteaction
0•aaaaDécalage
1a•aaaaReduc : R2
3a•aaaSDécalage
4aa•aaSaReduc : R1
5aa•aaSDécalage
6aaa•aSaReduc : R1
7aaa•aSDécalage
8aaaa•Ssuccès

Écrire les décalages/réductions nécessaires pour reconnaître le fragment aaaa avec la grammaire récursive droite :

R1  S → aS
R2  S → a

Corrigé :

paschaîne d'entréelisteaction
0•aaaaDécalage
1a•aaaaDécalage
2aa•aaaaDécalage
3aaa•aaaaDécalage
4aaaa•aaaaReduc : R2
5aaaa•aaaSReduc : R1
6aaaa•aaSReduc : R1
7aaaa•aSReduc : R1
8aaaa•Ssuccès

Laquelle choisiriez-vous? Laquelle pour une analyse ascendante comme bison, ou pour une analyse descendante comme javacc

Corrigé :
Analyse descendante (LL): Récursivité droite obligatoire
Analyse ascendante (LR) : Récursivité gauche plus efficace

3.2bis Analyse "ligne à ligne"

Une application directe de l'exercice précédent est le schéma d'analyse syntaxique "ligne à ligne" souvent utilisé pour les exercices de travaux pratiques

Soit une spécification Bison de la forme :

%%
Liste_Lignes :          /* mot vide */          /* Règle 1 */ {Action1;}
             | Liste_Lignes PhraseCorrecte '\n' /* Règle 2 */ {Action2;}
PhraseCorrecte : .......
%%

Écrire les décalages/réductions nécessaires pour l'analyse LR d'un fichier contenant 0,1,2,... lignes avec une "PhraseCorrecte" par ligne.

Préciser quand sont exécutées les Actions 1 et 2.

Corrigé

On notera (cf. exercice suivant) que Bison rajoute de façon conventionnelle un "axiome" englobant sous la forme d'une règle 0 "$accept : Axiome_de_la_spec $end", où "$end" désigne le Token EOF (==0) et "$accept" identifie une terminaison correcte de l'analyse.

a) Fichier vide :

pasPile d'analyseaction
0•EOFRéduction Règle1 et Action1
1Liste_Lignes • EOFDécalage
2Liste_Lignes EOF •Accept. (Réduction Règle0)

b) Fichier monoligne :

pasPile d'analyseaction
0• PhraseCorrecte \n EOFRéduction Règle1 et Action1
1Liste_Lignes • PhraseCorrecte \n EOF"Meta-Décalage"
2Liste_Lignes PhraseCorrecte • \n EOFDécalage
3Liste_Lignes PhraseCorrecte \n • EOFRéduction Règle2 et Action2
4Liste_Lignes • EOFDécalage
5Liste_Lignes EOF •Accept (Réduction Règle0)

NB: "Meta-Décalage" veut dire ici la suite de shift/reduce réalisant l'analyse LR du symbole non-terminal "PhraseCorrecte"

c) Fichier multiligne :

Par récurrence, on voit que pour un fichier avec N lignes "• (PhraseCorrecte \n){N} EOF", il suffit de boucler N fois sur les étapes 1,2 et 3 de l'analyse précédente.

L'Action1 est donc toujours exécutée une seule fois en début de fichier. L'Action2 est exécutée après chaque fin de ligne et dans l'ordre des lignes (merci à la récursivité gauche !).

On notera que l'absence de "\n" juste avant la fin de fichier est une erreur de syntaxe. Ceci explique un warning courant "missing newline before EOF" dans beaucoup d'usage informatique.

3.3 Suppression de conflits en modifiant la grammaire

La grammaire suivante est ambiguë et engendre un conflit de type décalage/réduction.

ListeExp:
        | Expression
        | ListeExp Expression
;
Expression: NUMBER
;

On se donne les fichiers conflit0.flex, conflit0.bison et conflit.data.

Bison peut aider à diagnostiquer les conflits et fournit l'accès à l'automate de résolution LR. Pour cela, utiliser l'option "--report=state" ou "-v" :

bison --report=state conflit0.bison
more conflit0.output

Essayer d'analyser l'automate LR décrit dans le fichier "conflit0.output". (cf. mementoBison)
Suivant les versions de bison, et avec quelques outils complémentaires, il est aussi possible d'obtenir une visualisation graphique de l'automate par exemple sous la forme : SVG pour conflit0.output ou PNG pour conflit0.output

Corrigé

3.4 Grammaire intentionnellement ambiguë

Il a été vu en cours que la grammaire suivante est ambiguë :

Instruction   : If Instruction
              ;
IfInstruction : IF Expr Instruction
              | IF Expr Instruction ELSE Instruction
              ;
Expr    : ...

Le type de conflit induit par cette grammaire est-il de type décalage/réduction ou réduction/réduction? Comment est-il résolu par l'analyseur généré par Bison?

Corrigé :

Ce problème est connu sous le nom du dangling else. L'élimination de l'ambiguïté est ici possible en écrivant la grammaire sous la forme :

Ifinstr   : instr_close
          | instr_non_close
          ;
instr_close : IF expr instr_close ELSE instr_close
            | autre
;
instr_non_close : IF expr instr
                | IF expr instr_close ELSE instr_non_close

3.5 Conflit de type réduction/réduction

Trois exemples :

E → E + T | T | id | ...
T → id | number

/* expressions caml */
Exp → number | id | Exp - Exp | - Exp | Exp Exp |...

/* conflit issu du lookahead limité */
S → H1 b c x | H2 b c y
H1 → a | ...
H2 → a | ...

N.B. : Le plus souvent les conflits reduce/reduce sont des erreurs de conception de la grammaire avec des redondances de définitions.


CSC 4508, TELECOM SudParis, F. Silber-Chaussumier, P. Hennequin
Last modified: Mars 2015