2010-08-16 8 views
3

J'essaie d'écrire un analyseur en Java pour un langage simple similaire à Latex, c'est-à-dire qu'il contient beaucoup de texte non structuré avec un couple de \ commands [avec] {some} {parameters} entre. Les séquences d'échappement comme \\ doivent également être prises en compte. J'ai essayé de générer un analyseur pour cela avec JavaCC, mais il semble que les compilateurs de compilateurs comme JavaCC ne conviennent que pour du code hautement structuré (typique pour les langages de programmation généraux), pas pour des problèmes de latex. balisage. Jusqu'à présent, il semble que je doive aller bas niveau et écrire ma propre machine d'état fini. Donc, ma question est la suivante: quelle est la manière la plus simple d'analyser les entrées qui sont pour la plupart non structurées, avec seulement quelques commandes de type Latex entre les deux?Analyse du langage de type latex en Java

EDIT: Passer au niveau bas avec une machine à états finis est difficile car les commandes Latex peuvent être imbriquées, par ex. \ cmd1 {\ cmd2 {\ cmd3 {...}}}

+1

La ressource est canonique [Apprendre à écrire un compilateur] (http: //stackoverflow.com/questions/1669/learning-to-write-a-compiler). Votre problème pourrait bien être assez petit pour qu'une approche de descente récursive manuelle soit judicieuse. En outre, je pense que vous pourriez confondre le lexisme et l'analyse syntaxique, ce qui pourrait rendre cela plus difficile que cela. – dmckee

Répondre

4

Vous pouvez définir une grammaire pour accepter l'entrée Latex, en utilisant juste caractères comme jetons dans la distribution la plus défavorable. JavaCC devrait être très bien à cette fin. La bonne chose à propos d'une grammaire et d'un générateur d'analyseur est qu'elle peut analyser des choses avec lesquelles les FSA ont des problèmes, en particulier les structures imbriquées.

Une première coupe à votre grammaire pourrait être (je ne suis pas sûr que cela est valable JavaCC, mais il est raisonnable EBNF):

Latex = item* ; 
item = command | rawtext ; 
command = command arguments ; 
command = '\' letter (letter | digit)* ; -- might pick this up as lexeme 
letter = 'a' | 'b' | ... | 'z' ; 
digit= '0' | ... | '9' ; 
arguments = epsilon | '{' item* '}' ; 
rawtext = (letter | digit | whitespace | punctuationminusbackslash)+ ; -- might pick this up as lexeme 
whitespace = ' ' | '\t' | '\n' | '\:0D' ; 
punctuationminusbackslash = '!' | ... | '^' ; 
+0

Oui, cela ressemble à une solution valide. Mais je me demande si séparer le texte en jetons à caractère unique est une mauvaise performance ... –

+0

@python dude: à moins que vos fichiers latex ne soient énormes, je doute que cela compte beaucoup. Ce que vous avez demandé était le moyen le plus facile de le faire, c'est tout! Si vous voulez le rendre plus rapide, vous pouvez implémenter certains des non-terminaux (rawtext, etc.) comme des lexèmes plus traditionnels. J'ai légèrement modifié la grammaire pour rendre cela plus facile. –