Ce TP porte sur l'utilisation de fonctionnelles pour la reconnaissance de grammaires. Dans un premier temps, on utilisera un module compilé fourni qui donne les fonctionnelles pour construire une grammaire reconnaissant les expressions arithmétiques. Dans un second temps on recodera nous-même ce module.
Le module a récupéré se trouve sur ces pages, selon la version du compilateur :
Son interface est donnée sur cette page.
Pour utiliser ce module dans le toplevel, évaluer les lignes suivantes :
Vous pouvez voir l'interface du module en le renommant : le toplevel listera alors son contenu.
Écrire deux fonctions, permettant de transformer une liste de caractères en chaînes de caractères, et inversement.
Écrire un parseur lisant le premier caractère d'une liste de caractères en utilisant Parse.read_this.
Écrire un parseur lisant le premier caractère d'une liste de caractères, si celui-ci vérifie un prédicat passé en argument.
Écrire une fonction testant si un caractère est un chiffre :
Écrire une fonction retournant l'entier correspond à un chiffre (en utilisant int_of_char) :
Utiliser Parse.read_strict_sequence, Parse.keep_highest_score et -!- pour écrire un parseur qui lit une liste de caractères, ne retourne rien si le premier caractère n'est pas un chiffre, sinon lit autant de chiffres que possible et retourne l'entier correspondant.
On définit les expressions arithmétiques ainsi :
Du coup, le langage à parser sera composé de 4 sortes de lexèmes :
Définir un type token pour les lèxemes.
En vous inspirant de la lecture des entiers, coder un parseur pouvant lire une variable. Essayer de factoriser au mieux le code des deux fonctions.
Écrire un parseur lisant autant de caractères d'espacement que possible (éventuellement aucun). Puis écrire une fonction lisant un des quatre opérateurs.
On peut maintenant écrire le lexeur, qui transforme une liste de caractères en liste de lexèmes. Pour cela, on répète la lecture de caractères d'espacement suivi de la lecture d'une des sortes de lexème.
Coder maintenant le parseur.
Pour cela, notons qu'il n'est pas possible d'utiliser une grammaire récursive à gauche, puisque cela ferait boucler le processus de parsage. On utilise donc la grammaire suivante :
Nous aurons donc besoin de trois fonctions, une par non-terminal de la grammaire, définies de façon mutuellement récursive.
La suite du TP consiste à coder vous-même le module Parse. Cette partie ne sera pas noté dans le cadre de ce TP, mais dans le cadre du projet.