L3/TL — TP 1 Premiers pas de JavaCC

publicité
L3/TL — TP 1
Premiers pas de JavaCC
L’objectif de ce TP est de se familiariser avec l’outil d’analyse syntaxique JavaCC. Le travail
consiste à modifier et à compléter des fichiers fournis. Ces fichiers sont disponibles à l’adresse
suivante :
http://circe.univ-fcomte.fr/Jerome-Voinot/TL/TP1/
1
Analyse lexicale
Le but de ces exercices est, d’une part, de se familiariser avec l’analyseur lexical de JavaCC
(lexer) et d’autre part, d’appliquer les connaissances sur les expressions régulières vues en cours.
Le dossier source contient deux fichiers.
1. Exercice1.jj, qui est reproduit dans la figure 1.
2. Lanceur1.java, qui est reproduit dans la figure 2.
Exercice1.jj contient un analyseur syntaxique au format javaCC. Il se compile avec la commande suivante : javacc Exercice1.jj
PARSER_BEGIN(Exercice1)
public class Exercice1 { }
PARSER_END(Exercice1)
/* --------------------- Regles lexicales
SKIP: {
" " | "\r" | "\t"
}
------------------------ */
TOKEN: {
<EOL: "\n" >
| < ALETTER: "a">
| < AWORD: (<ALETTER>)+ >
}
void start(): {System.out.print("start parsing");}{
<AWORD>
}
Fig. 1 – Fichier Exercice1.jj
Le compilateur crée un certain nombre de fichiers sources Java. Ce sont les sources de l’analyseur syntaxique correspondant au fichier Exercice1.jj. En particulier, un fichier Exercice1.java
1
est créé. C’est la classe principale du parser (analyseur syntaxique). La classe Lanceur1.java permet de l’exécuter.
La seconde étape est de compiler les sources avec la commande : javac *.java Puis on peut
exécuter le parser par la commande : java Lanceur1
public class Lanceur1 {
public static void main (String args[]) throws ParseException {
Exercice1 parser = new Exercice1(System.in);
parser.start();
}
}
Fig. 2 – Fichier Lanceur1.java
Exercices
1. Taper les mots aa, aaa, aaaaa, b ... Que constatez vous ?
2. Taper le mot a. Est-il accepté ? Remplacer dans le fichier .jj la ligne <ALETTER: "a"> par la
ligne <#ALETTER: "a">. Que constatez-vous ? A présent, l’analyseur syntaxique Exercice1.jj
reconnaı̂t les mots du langage correspondant à l’expression régulière (a)+ .
3. Ecrire les règles lexicales et syntaxiques permettant de reconnaı̂tre les langages suivants :
(a + b)+ , a∗ |b+ , a.(b+ ).a.
4. La règle lexicale suivante permet de reconnaı̂tre un chiffre :
<DIGIT: [0-9]>
Intégrez-la dans votre parseur. Puis, en vous inspirant de ce modèle, écrivez les règles lexicales
permettant de décrire un nombre entier <INT> , une chaı̂ne de caractères <STRING>, une
chaı̂ne de caractères en majuscules, une chaı̂ne de caractères commençant par "a".
2
Analyse syntaxique
Les expressions régulières ne permettent pas de reconnaı̂tre des langages algébriques tels que
L2 = {an .c.bn | n ≥ 0}.
Pour reconnaı̂tre ce genre de langages, il faut utiliser des règles syntaxiques. Par exemple, la
grammaire du fichier Exercie2.jj (reproduit dans la figure 3) reconnaı̂t le langage L2 .
2.1
Utilisation des règles syntaxiques
Le but de cet exercice est de construire un parser pour une structure if ... then ... else à l’aide
de règles syntaxiques.
1. Définir dans le lexer la reconnaissance des mots du langage.
2. Définir les règles syntaxiques pour reconnaı̂tre le langage suivant :
if (<STRING>) {<STRING>} else {<STRING>}
où <STRING> reconnaı̂t une chaı̂ne de caractères quelconque.
3. Transformer votre grammaire afin d’autoriser l’utilisation d’une autre structure if imbriquée.
Par exemple, cette grammaire doit engendrer
if ( a) { if (b){c} else {d} } else {e}
2
PARSER_BEGIN(Exercice2)
public class Exercice2 { }
PARSER_END(Exercice2)
/* --------------------- Regles lexicales
SKIP: {
" " | "\r" | "\t"
}
------------------------ */
TOKEN: {
<EOL: "\n" >
| < ALETTER: "a">
| < BLETTER: "b">
| < CLETTER: "c">
}
void start(): {}{
<ALETTER> start() <BLETTER> | end()
}
void end(): {} {
<CLETTER>
}
Fig. 3 – Fichier Exercice2.jj
2.2
Reconnnaı̂tre une expression arithmétique
Le dernier exercice consiste à créer, dans un fichier Exercice3.jj, un parser pour les expressions arithmétiques. Ces expressions sont constituées de constantes (nombres), du signe "+" et du
signe "*".
Indication : Pour ces expressions, il faut d’abord trouver sur papier une grammaire sans récursivité
gauche, sans , et qui tienne compte de la priorité de la multiplication sur l’addition.
3
Téléchargement