Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Grammaires formelles et dérivations

Après cette leçon: Je peux utiliser une grammaire pour décider si un texte est valide.

Leçon de 55 min6 commandesLab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Pourquoi un tableur refuse une parenthèse oubliée

Une grammaire est un ensemble de règles qui décrit comment fabriquer tous les textes valides d’un langage. Elle permet de décider si un texte est correct, et de voir comment il est construit.

Un tableur accepte =(2+3)*4 mais refuse =(2+3*4. Une grammaire explique pourquoi : chaque parenthèse ouverte doit être fermée au même niveau. Vous allez lire des règles, dériver des textes avec elles, puis vérifier des parenthèses.

À la fin de cette leçon

Remarque

Je peux utiliser une grammaire pour décider si un texte est valide.

Mots-clés

MotCe que ça veut direExemple
Grammaireun ensemble de règles qui décrit les textes valides
Règleune ligne qui dit par quoi remplacer un symboleP → ( P ) P
Symbole non terminalun nom qui sera encore remplacéP
Symbole terminalun caractère qui reste dans le texte final(
Dérivationla suite de remplacements qui mène au texte
Symbole de départle symbole par lequel on commence

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une grammaire remplace des symboles

Une grammaire part d’un symbole de départ et applique des règles. Chaque règle remplace un symbole non terminal par une suite de symboles.

Les symboles terminaux sont les caractères du texte final : ils ne sont plus remplacés. Voici la grammaire des parenthèses bien emboîtées. Son seul non terminal est P, et c’est aussi le symbole de départ.

Les deux règles des parenthèses

RègleSe litRôle
R1 : P → ( P ) PP devient une parenthèse ouvrante, un P, une fermante, puis un autre PEmboîte et enchaîne
R2 : P → videP disparaîtArrête la dérivation

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Exemple travaillé : dériver (())

ÉtapeTexte obtenuRègle appliquée
0PDépart
1( P ) PR1 sur P
2( ( P ) P ) PR1 sur le premier P
3( ( ) P ) PR2 sur le premier P
4( ( ) ) PR2 sur le premier P
5( ( ) )R2 sur le dernier P : fini

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Vérifier un texte : lire les règles à l’envers

Dériver fabrique un texte valide. Pour vérifier un texte donné, on fait l’inverse : on remplace une suite de symboles par le non terminal qui la produit.

Pour les parenthèses, la règle R1 lue à l’envers efface une paire collée (). Si le texte devient vide, il vient de la grammaire. S’il reste des symboles et aucune paire à effacer, il est incorrect.

Exemple travaillé : réduire ([]{}) puis ([)]

TextePaire collée effacéeTexte restant
([]{})[]({})
({}){}()
()()vide : texte valide
([)]Aucune : [ et ) sont collés([)] : texte incorrect

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Effacer les paires, étape par étape

Code: python
# On efface les paires "()" jusqu'à ce qu'il n'en reste plus.
texte = "(()())"
print(texte)
while "()" in texte:
    texte = texte.replace("()", "")
    print("->", texte)
if texte == "":
    print("texte équilibré")
else:
    print("texte incorrect")
# Remplacez le texte par "(()", puis relancez.

Une grammaire ambiguë donne deux arbres

Un même texte peut avoir deux arbres de dérivation. La grammaire est alors ambiguë.

Prenons 1+2*3 avec une grammaire d’expressions sans priorité. Un arbre regroupe 1+2 d’abord. L’autre regroupe 2*3 d’abord. Les deux textes sont valides, mais les résultats diffèrent.

Exemple travaillé : deux arbres pour 1+2*3

ArbreRegroupementRésultat
Arbre 1(1+2)*39
Arbre 21+(2*3)7

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Le fichier calc.y est une vraie grammaire

Le labo contient une grammaire écrite pour l’outil bison, dans ~/compiler/calc.y. Chaque règle commence par un nom suivi de deux-points. La barre | sépare les alternatives d’une même règle.

Entre l’arbre 1 et l’arbre 2, ce fichier choisit avec des lignes %left : la multiplication passe avant l’addition. Les premiers Runs lisent les règles. Les suivants construisent la calculatrice et lui envoient des parenthèses.

Les trois règles de calc.y

Commande
grep -E "^(lines|line|expr) *:" ~/compiler/calc.y

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Compter les lignes d’alternative

Commande
grep -c "^ *|" ~/compiler/calc.y

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Aller dans le dossier du compilateur

Commande
cd ~/compiler

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Construire la calculatrice

Commande
make

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Des parenthèses bien emboîtées

Commande
echo "((2+3)*4)" | ./calc

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une parenthèse oubliée

Commande
echo "(2+3" | ./calc

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Erreur fréquente

Attention

Beaucoup de gens pensent qu’une grammaire calcule le résultat d’une expression. Elle décrit seulement quels textes sont valides et comment ils s’emboîtent. Le calcul vient d’actions ajoutées aux règles, comme celles de calc.y.

Pour aller plus loin

Voici des mots : ab, aabb, aaabb, avec autant de a que de b. Écrivez une grammaire pour eux : S → a S b, et S → a b. Dérivez aaabbb étape par étape.

Expliquez ensuite pourquoi un motif comme a+b+ ne suffit pas pour cette forme.

À propos de ce labo et de sa source: Lab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.