Je souhaite analyser les langues spécifiques au domaine défini par l'utilisateur. Ces langages sont généralement proches des notations mathématiques (je n'analyse pas un langage naturel). Les utilisateurs définissent leur DSL dans une notation BNF, comme ceci:
expr ::= LiteralInteger
| ( expr )
| expr + expr
| expr * expr
L'entrée comme 1 + ( 2 * 3 )
doit être acceptée, tandis que l'entrée comme 1 +
doit être rejetée comme incorrecte, et l'entrée comme 1 + 2 * 3
doit être rejetée comme ambiguë.
Une difficulté centrale ici est de faire face aux grammaires ambiguës de manière conviviale. Limiter la grammaire pour qu'elle ne soit pas ambiguë n'est pas une option: c'est ainsi que la langue est - l'idée est que les écrivains préfèrent omettre les parenthèses lorsqu'elles ne sont pas nécessaires pour éviter toute ambiguïté. Tant qu'une expression n'est pas ambiguë, je dois l'analyser, et si elle ne l'est pas, je dois la rejeter.
Mon analyseur doit fonctionner sur n'importe quelle grammaire sans contexte, même ambiguë, et doit accepter toutes les entrées sans ambiguïté. J'ai besoin de l'arbre d'analyse pour toutes les entrées acceptées. Pour une entrée invalide ou ambiguë, je souhaite idéalement de bons messages d'erreur, mais pour commencer, je prendrai ce que je peux obtenir.
J'invoquerai généralement l'analyseur sur des entrées relativement courtes, avec une entrée plus longue occasionnelle. Ainsi, l'algorithme asymptotiquement plus rapide n'est peut-être pas le meilleur choix. Je voudrais optimiser pour une distribution d'environ 80% d'entrées de moins de 20 symboles de long, 19% entre 20 et 50 symboles et 1% d'entrées plus longues rares. La vitesse des entrées invalides n'est pas une préoccupation majeure. De plus, je m'attends à une modification de la DSL toutes les 1000 à 100 000 entrées; Je peux passer quelques secondes à prétraiter ma grammaire, pas quelques minutes.
Quel (s) algorithme (s) d'analyse dois-je étudier, compte tenu de mes tailles d'entrée typiques? Le rapport d'erreurs doit-il être un facteur dans ma sélection, ou dois-je me concentrer sur l'analyse des entrées sans ambiguïté et éventuellement exécuter un analyseur complètement distinct et plus lent pour fournir un retour d'erreur?
(Dans le projet où j'avais besoin de cela (il y a quelque temps), j'ai utilisé CYK , qui n'était pas trop difficile à implémenter et fonctionnait correctement pour mes tailles d'entrée, mais n'a pas produit de très belles erreurs.)
x+y+z
.
+
, donc x+y+z
est en effet ambigu et donc erroné.