Archive

Archives pour 01/2009

Le même avec ANTLR

16/01/2009

Juste pour la forme, j’avais parsé mon document avec jparsec, voici la même chose, mais ce coup-ci avec ANTLR.

ANTLR, c’est beaucoup plus classique : une grammaire dans un langage particulier, et on génère le code du parser a partir de cette grammaire. Son gros point fort, c’est ANTLRWorks, un chouette outil d’édition et surtout de débug de grammaires. C’est encore perfectible, surtout au niveau de l’ergonomie, mais ça remplit son office.

Le document à parser :

{abc|123|tralala}
{cde||youpie|tsoin tsoin|}

Chaque ligne est une étiquette, le nombre de champs est variable, et les champs vides sont autorisés. On veut récupérer un arbre :

1
2
3
4
grammar Etiquettes;
 
options { output=AST; }
tokens { ETIQUETTE; FIELD; }

Par convention, les tokens arbitraires sont tout en majuscules, les règles du lexer commencent par une majuscule, et les règles du parser par une minuscule. La règle principale s’appelle expr, et décrit l’ensemble du document.

La liste des tokens que le lexer doit repérer est assez claire :

5
6
7
8
9
Opening	:	'{';
Closing	:	'}';
Separator:	'|';
EndOfLine :	'n';
Text	:	~(Separator | Opening | Closing | EndOfLine)+;

Le texte, c’est tout ce qui n’est pas autre chose. J’imagine qu’il doit y avoir un moyen plus simple de le spécifier, mais je ne l’ai pas trouvé.

A partir de cet ensemble de tokens, on peut enfin construire notre document :

10
11
12
expr	:	etiquette+;
etiquette:	Opening field (Separator field)* Closing EndOfLine? -> ^(ETIQUETTE field+);
field	:	Text? -> ^(FIELD Text?);

On veut toujours parser une ou plusieurs étiquettes.
Une étiquette est construite à partir d’une ouverture, puis d’un ensemble de champs, d’une fermeture, et optionnellement d’une fin de ligne. Ce qui suit les flèches (->), c’est ce qu’on veut remonter dans l’arbre.

Avec tout ça, on peut enfin lancer le débugger d’ANTLRWorks sur notre petit document, et on obtient ceci :
Arbre généré

Il reste encore a récupérer l’arbre coté Java, mais c’est assez simple.

Si je voulais comparer avec ma version précédente utilisant jparsec, ça prends plus de code, ça demande une génération de code + parcours manuel de l’arbre, mais c’est plus clair. Je n’ai pas comparé les performances.

Je pense que pour des documents plus complexe, je préfèrerais utiliser ANTLR, c’est plus simple a tester.

Développement