TP 3 - Introduction à ANTLR4. Lexer

Ce TP est destiné à vous présenter le fonctionnement d'un lexer, son but étant de diviser un texte dans des parties identifiables, appelées jetons (tokens), comme dans l'exemple suivant.

En informatique, on va réaliser cette division à l'aide de l'outil ANTLR, spécialement créé pour traiter les textes structurés.

ANTLR4

ANTLR (ANother Tool for Language Recognition) est un générateur d'analyseurs pour lire, traiter, exécuter ou traduire du texte structuré ou des fichiers binaires. Il est largement utilisé pour créer des langages, des outils et des frameworks. À partir d'une description de langage formel, ANTLR génère un analyseur pour ce langage qui peut automatiquement créer des arbres d'analyse, dont on va discuter dans les cours et les TPs suivants. ANTLR génère également automatiquement des arborescences qu'on peut utiliser pour visiter les nœuds de ces arbres afin d'exécuter du code spécifique à l'application.

Configuration

L'outil nécessaire pour générer du code à partir d'ANTLR4 est écrit en Java. Donc, on a besoin seulement de l'archive ANTLR4 et d'un plug-in specialise pour Intelij.

Installation globale

  1. Télécharger le runtime complet d'ANTLR4 pour Java depuis ce lien. Le fichier .jar doivent etre sauvegardé dans un dossier spécial que vous devrez créer sur votre ordinateur, C:\Javalib.
  2. Ajouter antlr-4.11.1-complete.jar à la variable d'environnement CLASSPATH (aussi pour les variables de systeme que pour celles de votre utilisateur). Vous pouvez lire plus sur les variables d'environnement ici.
  3. Créer 2 fichiers batch.
    1. Le fichier antlr4.bat permet d'utiliser antlr4 dans la ligne de commande depuis n'importe quel fichier. Il doit contenir la commande java org.antlr.v4.Tool %.
    2. Le fichier grun.bat est utilisé pour tester le fichier d'entrée et pour afficher l'arbre d'analyse sous des formes différentes. Il doit contenir la commande java org.antlr.v4.runtime.misc.TestRig %*.
  4. Ajouter le dossier C:\Javalib a la variable d'environnement PATH.
  5. Vérifier l'installation en tapant antlr4 dans le Command Prompt.

Pour plus d'informations, vous pouvez consulter ce tutoriel.

Installation dans Intelij

  1. Telecharger le plugin ANTLR4 pour Intelij depuis ce lien. Redémarrer le programme Intelij apres l'installation.
  2. Créer un nouveau projet en Intelij et assurez-vous que c'est un project type 'Maven'.
  3. Entrez dans 'File > Settings' et assurez-vous que le plugin 'ANTLR v4' est active.
  4. Dans le fichier 'pom.xml', ecrivez les lignes suivantes, pour ajouter l'archive ANTLR dans notre projet.
    <dependencies>
        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-runtime</artifactId>
            <version>4.11.1</version>
        </dependency>
    </dependencies>

  5. On doit aussi ajouter le fichier '.jar' dans le project, pour etre reconnu par Intelij. Entrez dans 'File > Project Structure', appuyez sur le menu 'Modules' et puis sur le boutton '+', et ajouter le fichier '.jar' qui est dans le directoire 'C:\Javalib'. Puis, appuyez sur 'Apply' et 'OK'.
  6. Le resulat sera:

Lexer

En informatique, l'analyse lexicale, le lexing ou la tokenisation est le processus de conversion d'une séquence de caractères (comme dans un programme informatique) en une séquence de jetons (chaînes avec une signification attribuée et donc identifiée). Un programme qui effectue une analyse lexicale peut être appelé un lexer.

Un lexer est généralement combiné avec un parser, qui analysent ensemble la syntaxe des langages de programmation, des pages Web, etc. Dans ce chapitre, nous approfondirons uniquement les principes de construction d'un lexer, et nous discuterons des autres composants dans les TPs suivants.

Vous pouvez construire un lexer de deux façons:

  • Ecrire un programme qui utilise des expressions régulières et faire correspondre ces expressions régulières à aux jetons
  • Utilisez un générateur de lexer qui reçoit les expressions régulières et écrit le lexer pour vous

Rappel - Expressions régulières

Character Description Exemple
* Zéro ou plusieurs fois a*, (ab)*
+ Une ou plusieurs fois a+, (ab)+
? Zéro ou une fois a?, (ab)?
^ début de string ^ab*
$ fin de string b*a$
. tout symbole .
[ ] Ensemble [abc]
\s Espace blanc a\sb
[^ ] ensemble complémentaire [^abc]
( ) groupe (abc)+
| Ou a | b, (ab) | (ba)
{n} n fois a{3}
{n,m} minimum n, maximum m a{3,7}
\w alphanumérique et _ \w
\t TAB a\ta*
\n fin de ligne a\nb
\r retour chariot a\rb
a(?!b) a seulement si non suivi par b a(?!b)
a(?=b) a seulement si suivi par b a(?=b)
( ) group a(ab)a

Lexer en ANTLR4

Maintenant, nous devons ecrire le premier fichier '.g4', qui va acontenir toutes les regles de grammaire que nouv voulons avoir dans notre programme. Faisez un nouveau fichier 'alf.g4', qui va avoir les lignes suivantes:

grammar alf;

main: 'Hello ' NAME '!';
NAME: ([A-Za-z]+);

On peut observer la définition d'un token (à l'aide des expressions régulières), NAME pour identifier le nom introduit.

Après avoir créé ce fichier, on peut voir l'arbre generee par ANTLR, dans le menu 'ANTLR Preview'. En gauche, vous pouvez ecrire le texte qui va etre analyse, et en droit est l'arbre avec tokens.

Pour utiliser la grammaire dans un programme, on doit premierement configurer ou sont generees les fichiers necessaires pour l'analyse ANTLR.

  1. Creer un nouveau directoire 'alfLanguage', et marquer le 'Generated Sources Root'. Ce type de directoire signifie qu'il a seulement des fichiers read-only, qui peuvent etre importeed dans Main.
  2. Clic-droit sur le fichier de grammaire 'alf.g4' et appuyez sur 'Configure ANTLR…'. Le directoire pour output va etre 'alfLanguage', et le paquet qui va contenir tous les fichiers gennerees va etre 'com.alf.parser'.
  3. Clic-droit sur le fichier de grammaire 'alf.g4' et appuyez sur 'Generate ANTLR Recognizer'. On peut voir maintenant le directoire alfLanguage populee avec plusieurs fichiers:
  • Lexer: les règles de lexer sont destinées à créer des objets token correspondants
  • Parser: les règles de parser sont responsables pour l'analyse du langage
  • Listener: fournit des méthodes appelées indépendamment par un objet walker fourni par ANTLR
  • Visitor: contient des méthodes qui doivent accompagner (walk) leurs enfants avec des appels de visite explicites

L'étape suivante suppose la création de Main.java, où l'on doit écrire la structure du programme et gestionner le fichier d'entrée:

package org.example;
 
// Import generated files
import com.alf.parser.alfLexer;
import com.alf.parser.alfParser;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
 
public class Main {
    public static void main(String[] args) {
        // Create lexer from input string
        alfLexer lexer = new alfLexer(CharStreams.fromString("Hello ALF!"));
 
        // Create parser
        alfParser parser = new alfParser(new CommonTokenStream(lexer));
 
        // Parse the input, where `main` is the entry point you defined in the grammar file
        alfParser.MainContext tree = parser.main();
        System.out.println("Tokens: " + tree.children);
 
        // Now we can get each token from the input we introduced
        String name = tree.NAME().getText();
        System.out.println("Name intoduced: " + name);
    }
}

Après chaque modification apportée à la grammaire (fichier alf.g4), vous devez generer de nouveau les fichiers de ANTLR, avec clic-droit sur le fichier de grammaire > Generate ANTLR Recognizer

Exercices

  1. (Sans ANTLR) Traitez le tableau ci-dessous a l'aide des expressions régulières de sorte que chaque livre devienne un objet de type Book, avec les suivantes propriétés: titre (string), ISBN (number), et date de publication (string). (1p)
     String[] books_array = {"Engineering a Compiler,9780120884780,7th February 2011",
                    "Modern Operating Systems 4,9780133591620,21st March 2014",
                    "Computer Networks,9332518742,9th January 2010"};
  2. Installez ANTLR4 globalement, en suivant les étapes du laboratoire. (1p)
  3. Créez le programme complet présenté dans le tutoriel de ce TP (fichiers de configuration, fichier Alf.g4, fichier Main.java) et assurez-vous que son exécution est réalisée sans d'erreurs. Faites input string “Hello <votre nom>!”(1p)
  4. Affichez la liste des tokens: (1p)
    1. A l'aide des fonctions pour les strings, traitez le fichier Alf.tokens créé automatiquement par ANTLR et générez un HashMap qui ait comme clés l'indice de vos tokens et comme valeurs leur nom. (0.5p)
      {1='Hello ', 2='!', 3=NAME}
    2. Parcourez et affichez la liste des tokens (pour chaque token, affichez son nom et sa valeur comme dans l'exemple. Indice: Pour pouvoir afficher la liste des tokens, vous devrez inspecter la classe BufferedTokenStream et choisir une méthode qui retourne cette liste. Vous aurez aussi besoin de la fonction nextToken() pour parcourir le buffer de données. (0.5)
      [{ '10': 'INT', '\n': 'NEWLINE', '20': 'INT' }
  5. Ajoutez a votre fichier Alf.g4 des expressions régulières pour les jetons suivants: NUMBER - tout texte contenant uniquement des chiffres et PONCTUATION - différents signes de ponctuation. Utilisez le lexer créé dans l'exercice précédent pour afficher la liste des tokens pour le texte: Bonjour! Le TP d'ALF est de 8 a 10. (1p)
  6. Utilisez votre lexer pour analyser les jetons du fichier text_and_numbers.txt. Pour chaque ligne de ce fichier affichez le texte du jeton, le type, et la ligne du fichier ou il a été trouvé. (1p)
  7. Ecrivez un lexer qui reconnaît un sous-ensemble du langage Python. Pour chaque point de cet exercice, utilisez comme exemple une chaîne quelconque correspondant au langage Python, pour voir si votre programme peut: (3p)
    1. Reconnaître les mots-clés suivants: for, if, while, else, def, break, class
    2. Reconnaître les noms des fonctions: ils commencent par une lettre ou _ et sont suivis de n'importe quelle lettre ou chiffre
    3. Reconnaître les nombres entiers
    4. Reconnaître les nombres à reels
    5. Reconnaître les variables
    6. Reconnaître les opérateurs: ( ) , ; : + - * / = % { } [ ]
  8. Utilisez le lexer de l'exercice précédent pour le fichier program.py. Ecrivez chaque type de jeton, le texte qui lui correspond et la ligne où il a été trouvé. (1p)
  9. Bonus: Modifiez le lexer de l'exercice 7 pour qu'il reconnaisse aussi des chaînes de caractères (texte encapsulé entre ” ou '). (1p)
alf/laboratoare/03_fr_java.txt · Last modified: 2023/04/03 17:37 by alexandra.negoita02
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0