But
Le but de cette partie est d'écrire un analyseur syntaxique pour
le langage misc. Votre analyseur doit simplement vérifier que l'entrée
est syntaxiquement correcte mais ne doit pas construire l'arbre
syntaxique. Si l'entrée est correcte, votre analyseur doit donc
simplement s'arrêter, sinon, il doit signaler au moins une
erreur.
Travail à effectuer
Votre travail est de réaliser l'analyseur syntaxique en complétant
la classe Parser . Nous vous
suggérons d'utiliser la technique de la descente
récursive. Avec cette technique, la correspondance entre la
grammaire au format EBNF et le code source de l'analyseur syntaxique
est assez directe : à chaque règle de la grammaire correspond une
méthode de l'analyseur, méthode qui reconnaît les constructions
produites par cette règle; à la répétition ({} en EBNF)
correspond une boucle; à l'option ([] en EBNF) correspond
un test; et ainsi de suite. Reportez-vous au cours pour plus
d'informations au sujet de cette technique.
Bien que pour l'instant vous ne deviez pas construire d'arbre
syntaxique, nous vous conseillons de faire en sorte que toutes vos
méthodes d'analyse retournent déjà une valeur de type Tree ou Tree[] , car cela simplifiera sa
modification ultérieure. Pour l'instant, retournez simplement un arbre
null
Gestion des erreurs
La classe Parser fournit
deux méthodes error pour signaler des erreurs. Si
celles-ci ne conviennent pas, vous pouvez aussi directement appeler
les méthodes de la classe Global .
Pour cette partie, tout comme pour la précédente, vous pouvez vous
contenter de détecter la première erreur. C'est pourquoi, les deux
méthodes error appellent une méthode fatal
de la classe Global . Tout
appel à l'une de ces deux méthodes termine donc aussi l'analyse en
cours. Si vous désirez pouvoir signaler plusieurs erreurs, il vous
faudra probablement changer cela et remplacer l'appel à
fatal par un appel à error .
Si vous voulez savoir pourquoi les deux méthodes
error retournent une valeur du type Error ,
lisez le commentaire à propos des méthodes fatal ici.
Fichiers
Ci-dessous, les fichiers qui vous sont fournis pour cette partie.
Tree.java : Cette classe acueillera,
par la suite, la définition des différents noeuds de l'arbre
syntaxique. Pour l'instant elle est vide et sert uniquement à définir
la classe Tree afin que les
méthodes de l'analyseur syntaxique puissent être déclarées avec un tel
type de retour.
Parser.java : Cette classe implante
l'analyseur syntaxique. A vous d'écrire la partie manquante du
code.
ParserTest.java : Cette classe
définit un programme qui vous permet de tester votre analyseur
syntaxique. Il lit un fichier source et l'analyse. La syntaxe de la
ligne de commande est la même que celle de ScannerTest.java, mais, comme il n'y a
pas de sortie, le ficher objet ne sert à rien.
Pour pouvoir continuer à utiliser le Makefile, il vous faut y déclarer les
nouveaux fichiers. Pour cela, ajoutez y les lignes suivantes :
JC_SOURCES += src/misc/Parser.java
JC_SOURCES += src/misc/ParserTest.java
JC_SOURCES += src/misc/Tree.java
Projet en Scala
Pour réaliser le projet en Scala, utilisez les fichiers suivant au lieu de ceux donnés ci-dessus.
Tree.scala : Cette classe acueillera,
par la suite, la définition des différents noeuds de l'arbre
syntaxique. Pour l'instant elle est vide et sert uniquement à définir
la classe Tree afin que les
méthodes de l'analyseur syntaxique puissent être déclarées avec un tel
type de retour.
Parser.scala : Cette classe implante
l'analyseur syntaxique. A vous d'écrire la partie manquante du
code.
ParserTest.scala : Cette
classe définit un programme qui vous permet de tester votre analyseur
syntaxique. Il lit un fichier source et l'analyse. La syntaxe de la
ligne de commande est la même que celle de ScannerTest.java, mais, comme il n'y a
pas de sortie, le ficher objet ne sert à rien.
Pour pouvoir utiliser ParserTest.scala, il vous faut deux
fichiers Java suplémentaires :
ScalaMain.java : Cette classe
fourni une base commune pour les programmes Scala.
ScalaMainRunnable.java :
Cette interface est utilisée par la classe ScalaMain .
Ci-dessous un fichier Makefile pour compiler les fichier
.java puis les fichier .scala .
Makefile : Fichier
Makefile pour le projet en Scala.
Pour pouvoir utilisez Parser.scala,
vous devez transformer l'interface Tokens en une classe
abstraite et déclarer tous ses membres public static
final . Elle devrait donc ressembler à ça. Il vous faut ensuite remplacer le
implements par un extends dans la classe Scanner et dans la classe ScannerTest , il faut
supprimer le implements Tokens et remplacer
EOF par Tokens.EOF .
Pour lancer le programme de test, vous devez utiliser la commande
java , mais vous devez inclure dans le classpath
l'archive scala.jar qui contient les classes du
runtime Scala. Sur les machines en IN3, cette archive se trouve
dans le répertoire suivant :
/home/iclamp/local/packages/scala/lib/
Il vous faut donc lancer une commande qui ressemble à ça :
java -classpath /home/iclamp/local/packages/scala/lib/scala.jar:./classes ParserTest <options> [fichier-source [fichier-objet]]
Pour éviter de devoir à chaque fois spécifier l'option
-classpath , vous pouvez redéfinir la variable
d'environnement CLASSPATH afin qu'elle contiennent
l'archive scala.jar et votre répertoire
classes .
|