Architecture Du Moteur De Grammaire

Concept

Le moteur de grammaire développé par MRules a été conçu afin de respecter les objectifs suivants :

  • Permettre de lire un texte correspondant à une syntaxe donnée et le transformer en une grappe d’Objets Java.
  • Pouvoir concevoir de toute pièce une grammaire évoluée en écrivant peu voire pas de code.
  • Permettre de valider syntaxiquement le texte source et proposer une fonctionnalité d’aide à l’écriture (auto complétion).

Bien qu’orienté vers la création de grammaires fonctionnelles (proches du langage naturel), cet outil permet également de créer rapidement et simplement des grammaires techniques.

Le projet de démonstration montre par exemple comment créer en quelques lignes de configuration un parser JSON, respectant les standards officiels, et retournant le résultat lu sous forme d’une Map d’Objets.

Fonctionnement

L’objectif est de découper le texte lu selon des pattern. Un pattern est représenté après lecture sous la forme d’un Objet Java. Un pattern est lu dans son intégralité par un objet nommé « Lexer ». Un lexer est composé :

  • D’un Matcher de début, chargé de détecter le commencement d’un pattern.
  • De zéro, un ou plusieurs Blocks.
  • Éventuellement d’un Matcher de fin, chargé de finaliser la lecture d’un pattern.

Un Matcher peut être :

  • La détection d’un texte fixe
  • La détection d’une expression régulière
  • La détection d’un Lexer enfant
  • La combinaison (Et / Ou) de plusieurs Matcher

Un block est la lecture d’un pattern enfant, donc l’exécution d’un Lexer enfant.

Composants

Le diagramme ci-dessous présente une vue globale des composants de la librairie.

Architecture globale du moteur de grammaire MRules
Architecture globale du moteur de grammaire MRules

Documentation

Le module fournit également les utilitaires nécessaires pour générer automatiquement la documentation des grammaires créées. Cette documentation est composée de :

  • Les informations globales sur la grammaire
  • La liste des lexers :
    • Leur description (si disponible) et les informations générales
    • Le contenu détaillé
    • Un schéma syntaxique

Seul le rendu de cette documentation n’est pas inclus dans le module. Une extension permettant la génération au format HTML a été créée. Il est également envisageable de créer d’autre format cible en écrivant d’autres extensions de rendu.

Exemple

Prenons l’exemple de la phrase suivante :

"Si la température actuelle est supérieure à 18 degrés Celcius alors éteindre le chauffage sinon allumer le chauffage."

Le découpage s’effectuera comme suit :

Matcher de début : "Si".
  |--> On entre dans une action conditionnée.
  |--> On instancie l'objet correspondant.
  |--- Premier block: la condition
         |--> Composition de 3 matchers (valeur, opérateur, valeur) 
         |--> Matcher de début : "la température actuelle". 
                |--> Block, créer un objet récupérant la température.
         |--> Matcher de début : "est supérieure à".
                |--> Block, instancier opérateur de comparaison.
         |--> Matcher de début : "18".
                |--> Block, instancier une température.
                |--> Matcher de fin : "degrés celcius". Injecter l'unité.
  |--> De même avec les blocks d'action "si vrai" et "si faux".