Archive

Articles taggués ‘JParsec’

Un parser très basique avec JParsec

05/01/2009

Juste pour ma mémoire, comme j’ai passé la matinée là dessus sans trouver comment renvoyer des données…

On a un document très simple à parser :

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

On veut évidement récupérer des listes de chaines, sans se poser de question. Tellement simple qu’on pourrait le faire a la main. Mais voilà, moi, j’avais envie d’essayer JParsec, et tous les exemples sont terriblement plus compliqués (et surtout, plus orientés langages et opérations).

L’idée de parsec, c’est de faire des parsers directement dans le langage du programme, et de les combiner, plutôt que de rédiger une grammaire qui sera convertie (genre antlr). Ce qui me plait la dedans, c’est l’impression de pouvoir y aller progressivement.

Bref.

L’essentiel du boulot est dans la classe Scanners. Pensez à regarder les méthodes, et pas que les champs, c’est ce qui m’a foutu dedans ce matin (on va dire que j’étais fatigué).

Donc pour éviter d’avoir a préfixer tout ce qu’on va appeler :

1
import static org.codehaus.jparsec.Scanners.*;

Et on combine. Commençons par ce qu’on veut récupérer, c’est a dire les caractères entre les pipes :

1
Parser<String> content = notAmong("|}").many().source();

La méthode source(), c’est l’astuce pour récupérer le texte qui matche. Je ne comprends pas pourquoi ces parseurs ne renvoient pas la chaine directement.

Une fois qu’on a cette chaine, on peut récupérer une liste, puis la ligne complète :

2
3
Parser<List<String>> enclosed = content.sepBy(isChar('|'));
Parser<List<String>> line = enclosed.between(isChar('{'), isChar('}'));

Il ne nous reste plus qu’a boucler sur les lignes :

4
5
6
Parser<Void> eof = (Parser<Void>)Parsers.EOF; 
Parser<Void> endOfLine = among("rn").or(eof);
Parser<List<List<String>>> lines = line.endBy(endOfLine);

Et voilà, on y est :

7
System.out.println(lines.parse(document));

=> [[abc, 123, tralala], [cde, , youpie, tsoin tsoin, ]]

Résultat des opérations : 6 lignes de code pour récupérer des données structurées.

Développement