JavaCC 21 est la continuation de travail sur le vénérable générateur de code JavaCC, initialement développé chez Sun Microsystems dans les années 90 et dont le code source qui fut libéré en 2003, sous une licence Open Source libérale. JavaCC 21 est la version plus avancée de JavaCC en ce moment. Il y a beaucoup de nouvelles fonctionnalités (et il y en aura davantage bientôt!). D'ailleurs, certains bugs de longue date ont été réparés. (Enfin.)

(N.B. Le “21” de JavaCC 21 n'est pas un numéro de version. Ça fait simple partie du nom du projet et cela veut dire que c'est un JavaCC pour le 21ème siècle!)

Voici quelques faits saillants:

Support Actualisé du Langage Java

JavaCC 21 supporte le langage Java jusqu'à version JDK 13. Voir ici. La grammaire Java que JavaCC 21 utilise internellement peut être utilisée dans vos propres projets sans aucune restriction.

Les prédicats syntactiques fonctionnent correctement!

Avec JavaCC, limitation de longue date, c'est que les prédicats ne peuvent pas s'utiliser de façon récursive. Il s'agit d'un problème qui existe depuis 24 ans qu'on n'a jamais résolu. Comme conséquence, l'outil a toujours été moins utile que ce qu'il aurait dû être, vu qu'un usage moindrement sophistiqué implique typiquement des lookaheads récursifs et, tout simplement, ça ne fonctionnait pas. En JavaCC 21, ça marche enfin.

Une Syntaxe Simplifiée

Bien que la syntaxe originale fonctionne encore (et on la supportera dans le futur indéfini) JavaCC 21 offre une nouvelle syntaxe simplifiée]( qui est plus facile à écrire et lire. Parfois il s'agit d'une amélioration de lisibilité qui est absolument dramatique! Par exemple, où vous auriez écrit avant:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
    void FooBar() :
    {}
    {
        Foo() Bar()
    }
avec la nouvelle syntaxe simplifiée, vous pouvez maintenant écrire:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
    FooBar : Foo Bar ;
Les aspects plutôt lourds de la syntaxe LOOKAHEAD ont été simplifiés. Voir ici. Encore une fois, la nouvelle syntaxe offre parfois des améliorations dramatiques de clarté. Où vous auriez écrit avant:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
    LOOKAHEAD(Foo() Bar() Baz()) Foo() Bar() Baz()
En JavaCC 21, vous pouvez écrire:

Le nouveau signet jusqu'ici fournit aussi des grands gains en lisibilité et maintenabilité. Par exemple, où vous auriez écrit avant:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
    LOOKAHEAD(Foo() Bar()) Foo() Bar() Baz()
Vous pouvez écrire maintenant:

Ce nouvel élément syntactique =>|| s'appelle le signet jusqu'ici et il exprime de façon bien plus claire et économique l'idée que, quand on décide si on va entrer l'expansion Foo Bar Baz on scanne en avant jusqu'à la fin du Bar.

Les Prédicats "Lookbehind"

Lookbehind (regarder en arrière) est une nouvelle fonctionnalité en JavaCC 21 qui vous permet d'écrire des prédicats aux ]points de choix qui vérifient si on se trouve à un point donné dans un texte. Par exemple:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
    SCAN …\Foo => Bar
Le code ci-dessus utilise un prédicat *lookbehind* pour exprimer l'idée qu'on entre la production Bar seulement si on est déjà entré dans un Foo. Ou, par exemple:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
    SCAN ~\…\Foo => Foo
Ce code veut dire qu'on entre la production Foo si on n'est pas déjà dans un Foo. (Autrement dit, Foo n'est pas une production "rentrante".) Il s'agit d'une fonctionnalité très utile, déjà utilisée dans le développement interne. On n'a pas vu d'autres outils qui ont cette fonctionnalité.

Améliorations dans la Construction d'Arbres Syntactiques

JavaCC 21 se base sur la notion que la construction d'un AST (Abstract Syntax Tree) est l'usage normal (ou typique) de ce gendre d'outil. Bien que le package JavaCC original (20ème siècle) avait une fonctionnalité de construire les AST, le préprocesseur JJtree, cela a des problèmes d'utilisabilité de très longue date.

D'abord, grande partie du problème, ci qui fait que JJTree soit assez lourd à utiliser, c'est précisément qu'il s'agit d'un préprocesseur! En JavaCC 21, toute cette fonctionnalité est tout simplement dans l'outil de base et le parseur généré construit un AST par défaut. (La construction de l'arbre peut être éteint, tout de même.)

(NB. JavaCC 21 se sert de la même syntaxe pour les annotations de construction d'AST que JJTree.)

JavaCC 21 a une déclaration INJECT qui vous permet d'injecter du code Java dans n'importe quel fichier généré. Alors, on se débarrasse de cet anti-motif de modifier manuellement les fichiers générés.

Meilleur Code Généré

JavaCC 21 génère généralement du code bien plus lisible. D'ailleurs, le code généré est bien plus moderne. Considérons le champ Token.kind dans le fichier Token.java généré par l'outil original. Ce champ est un un entier (type primitif) et (contrairement à des bonnes pratiques archi-connues) il est publiquement accessible. Dans le fichier Token.java généré para JavaCC 21, la méthode Token.getType() renvoie un Enum (qui est type-safe) et tout le code du parseur généré qui utilisait des entiers pour représenter le type du Token, utilise maintenant des type-safe enums.

Le code généré par le JavaCC original donnait presque aucune information au sujet d'où le code généré provenait. Les parseurs générés par JavaCC 21 ont l'information ligne/colonne (relative au vrai fichier source, la grammaire JavaCC) et ils injectent information dans le stacktrace de ParseException sur la ligne/colonne dans le fichier grammaire.

Si vous voulez faire une comparaison côté à côté du code généré par le JavaCC original et celui généré par JavaCC 21, vous pouvez regarder ici.

Le code de JavaCC 21 lui-même est le fruit d'un nettoyage/refactorisation. La génération du code a été externalisé à des templates FreeMarker. Pour se faire idée de ce que ça veut dire dans la pratique, voici le template principal pour générer le code Java pour les productions grammaticales.

Diverses Améliorations côté Utilisabilité

En général, les paramètres par défaut de JavaCC 21 sont plus sensés, ce qui fait que l'outil est bien plus facile à utiliser pour les débutants. Voir ici.

JavaCC 21 est sous Développement Actif

Ceci, parmi tout, est peut-être le point plus important: le projet est à nouveau sous développement actif. Alors, les usagers peuvent s'attendre à de nouvelles fonctionnalités bientôt. Vu que la génération du code a été externalisé à des templates, la possibilité de générer des parseurs dans d'autres langages ne devrait pas être très loin. Un autre objectif qui devrait être assez proche, c'est c'est de pouvoir générer des parseurs fault-tolerant qui peuvent construire un AST même quand l'entrée contient des erreurs.

Une façon de se tenir à jour avec le projet JavaCC 21 est de s'abonner à notre newsfeed).

L'usage est vraiment assez simple. Comme on décrit ici) on invoque JavaCC 21 sur la ligne de commandes avec:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
    java -jar javacc-full.jar MyGrammar.javacc
Un ficher .jar récent est toujours disponible ici: https://javacc.com/download/javacc-full.jar. Alternativement, on peut obtenir le dernier code source de Github et faire un build:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
    git clone https://github.com/javacc21/javacc21.git
    cd javacc21
    ant jar test
Si vous vous intéressez à ce projet, comme usager ou collaborateur, vous pouvez nous écrire en anglais, français, ou espagnol. Vous pouvez aussi vous inscrire sur notre Discourse Forum et poster n'importe quelle question our suggestion.