jean-jacques.levy@inria.fr
9 février 1998
Les supports de cours sont enhttp://www.polytechnique.fr/poly/edu/informatique/ http://www.polytechnique.fr/poly/~levy/
Livres:
Introduction
Automates à pile
Un automate à pile (pushdown automata) est un n-uplet où
Q est un ensemble fini d'états,
est un alphabet (de terminaux ou tokens),
est un alphabet fini de symboles de pile,
est l'état initial,
est le symbole de pile initial,
est l'ensemble des états finaux,
est la fonction de transition
Déplacements élémentaires
veut dire que, dans l'état q, si le sommet de pile est Z et si la tête de lecture voit la lettre a, alors l'automate déplace sa tête de lecture vers la droite et peut aller non déterministiquement dans un des états qi en remplaçant la lettre du sommet de pile Z par le mot . (Par convention, la pile est lue de la gauche vers la droite en allant du sommet à sa base).
veut dire qu'on fait de même sans regarder le symbole sous la tête de lecture. Alors la tête de lecture ne se déplace pas vers la droite.
(M.P.Schutzenberger, 1962)
Configurations et acceptation
Une configuration est une paire où q est l'état courant et est le contenu de la pile.
si où ,
si et , et pour , .
L'automate M reconnait le langage T(M)
Acceptation
On peut aussi reconnaitre par pile vide, sans se servir de F.
Cela ne change pas la catégorie des langages reconnus.
Un automate à pile est déterministe si une seule transition est possible dans chaque configuration.
Théorème Les langages context-free sont les langages reconnus par les automates à pile.
Démonstration: évidente dans un sens. Légèrement plus compliquée dans l'autre sens.
Propriété de fermetures des langages context-free
Les langages context-free sont fermés par union, mais pas par intersection. Par exemple, et sont context-free, mais pas .
L'intersection d'un langage régulier et d'un context-free est un langage context-free.
Appelons homomorphisme toute application que l'on étend trivialement sur . Alors les langages context-free sont clos par homomorphisme. Mieux:
Théorème[Chomsky-Schutzenberger] Tout langage context-free est l'image par homomorphisme de l'intersection d'un langage de parenthèses (langage de Dyck) et d'un langage régulier.
Automates déterministes
Pour analyser les langages de programmation en temps linéaire, on veut des automates déterministes (DPDA, deterministic pushdown automata).
Les langages context-free déterministes sont les langages reconnaissables par un automate déterministe. Par exemple, le langage est context-free non déterministe.
[La conjecture sur l'équivalence des DPDA ne vient d'être résolue qu'en 1997 par Sénizergues de Bordeaux]
La programmation moderne utilise la récursion plutôt que les piles. Mais Yacc génère des analyseurs avec une pile. Le problème du déterminisme se retrouve aussi si on programme récursivement.
Analyse syntaxique
cf. le livre d'Andrew Appel
Récupération d'erreurs
En fait, on analyse syntaxiquement un langage et ses erreurs. Il est difficile de faire de bonnes récupérations d'erreurs. Typiquement on veut sauter au ;; suivant. Il faut donc savoir récupérer l'erreur soit grace à un token spécial error en yacc, soit en récupérant l'execption Parse_error en Caml, et en sautant manuellement les lexèmes jusqu'au ;; suivant, par exemple.
PCF: un petit langage fonctionnel
Un interpréteur
On construit une fonction d'évaluation
...
Déclarations locales et portées
Pour avoir des variables locales et des définitions locales, il faut donner un deuxième argument à la fonction d'évaluation, l'environnement qui décrit la liaison des variables locales.
est une liste d'association entre les noms des variables locales et leur valeur.
On redéfinit la fonction .
...
Valeurs fonctionnelles et application
Comment déclarer des fonctions et les appliquer? C'est simple dans PCF, il suffit de rajouter l'expression fonctionnelle et l'application e(e').
Les expressions pourront donner non seulement des valeurs scalaires, mais aussi des fermetures, i.e. un couple formé d'une expression et d'un environnement.
On ajoute simplement à l'évaluateur les règles:
où
Récursivité
Comme attendu, la récursivité introduite par est une simple variation sur l'évaluation de .
où
Exemples et exercices
On peut maintenant analyser et évaluer les petits programmes suivants:
letrec fact = fun x -> ifz x then 1 else x * fact (x-1) in fact(10);; letrec fib = fun x -> ifz x then 0 else ifz x-1 then 0 else fib (x-1) + fib(x-2) in fib(20);; let x = let y = 20 in y+3*y in let y = let y = 20 in x-y in x + y ;; let twice = fun f -> fun x -> f (f x) in let succ = fun x -> x+1 in twice (succ) (0);;