Ce que protège le dernier contrôle de l'analyseur
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 30 — Grammaires non contextuelles
Énoncé
L'analyseur du chapitre se termine par
s ();
if !pos <> n then raise Echec (* tout le mot doit être consommé *)
Que se passe-t-il si l'on retire cette ligne ? Donner deux mots qui seraient alors acceptés à tort.
Corrigé
Sans cette ligne, l'analyseur accepte tout mot dont un préfixe appartient au langage, et ignore ce qui suit.
Deux témoins, obtenus en exécutant les deux versions :
| Mot | avec le contrôle | sans le contrôle |
|---|---|---|
| `c` | accepté | accepté |
| `acbc` | accepté | accepté |
| `cc` | refusé | accepté à tort |
| `cab` | refusé | accepté à tort |
| `acb` | refusé | refusé |
| `aa` | refusé | refusé |
Sur cc, la fonction s lit le premier c par la règle , rend la main, et il reste un caractère que personne ne regarde. Sur cab, il en reste deux.
Pourquoi acb reste refusé : là, l'échec vient de l'intérieur — après a, la fonction t appelle s, qui exige un c et trouve un b. Le contrôle final n'attrape que les échecs par excès, pas ceux par défaut.
La leçon de spécification. Un analyseur par descente récursive répond en vérité à la question « un préfixe du mot est-il dans le langage ? ». La question demandée est « le mot est-il dans le langage ? ». Les deux ne se rejoignent qu'à la dernière ligne : on a écrit du code qui répond à une question voisine de celle qu'on posait.
Et l'on ne s'en aperçoit qu'aux frontières — le mot vide, le mot réduit à un préfixe valide, le mot valide suivi d'un caractère. C'est la règle du chapitre chap:discipline : aucun cas « du milieu » ne révèle cette faute-là.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.