42 votes

Quels sont les inconvénients du framework d'analyseur-générateur Spirit de boost.org?

Dans plusieurs questions, j'ai vu des recommandations pour le cadre d' analyse syntaxique-génératrice Spirit de boost.org , mais dans les commentaires, il y a des plaintes de la part de personnes utilisant Spirit qui ne sont pas heureuses. Est-ce que ces personnes vont prendre la parole et expliquer au reste d'entre nous quels sont les inconvénients ou les inconvénients de l'utilisation de Spirit?

37voto

Blaisorblade Points 3951

C'est une très bonne idée, et j'ai aimé ça, c'était surtout utile pour vraiment apprendre à utiliser les modèles C++.

Mais leur documentation recommande l'utilisation de l'esprit pour les petites et moyennes taille des analyseurs. Un analyseur syntaxique pour une pleine langue prendrait des années à compiler. Je vais en citer trois raisons.

  • Scannerless de l'analyse. Alors que c'est assez simple, lorsque le retour en arrière est nécessaire, elle peut ralentir l'analyseur. Il est en option si - un analyseur lexical pourrait être intégrée, voir le préprocesseur C construit avec l'Esprit. Une grammaire de ~300 lignes (y compris les deux .h et .fichiers cpp) compile (unoptimized) à un fichier de 6M avec GCC. Inline et maximum optimisations obtient que jusqu'à ~1,7 M.

  • Lenteur de l'analyse - il n'y a pas de vérification statique de la grammaire, ni de faire allusion à propos excessifs d'anticipation nécessaire, ni pour vérifier les erreurs de base, comme par exemple l'utilisation de la récursivité à gauche (ce qui conduit à une récursion infinie récursive de la descente des analyseurs LL grammaires). Récursion à gauche n'est pas vraiment dur d'un bug de la piste vers le bas, bien, mais trop d'anticipation pourrait causer exponentielle analyse de fois.

  • Lourd modèle d'utilisation - ce qui a des avantages certains, ceci a des répercussions sur les temps de compilation et de la taille du code. En outre, la définition de la grammaire doit normalement être visible pour tous les autres utilisateurs, un impact encore plus les temps de compilation. J'ai été en mesure de déplacer des grammaires pour .fichiers cpp par l'ajout explicite modèle instanciations avec les bons paramètres, mais il n'a pas été facile.

Mise à JOUR: ma réponse est limitée à mon expérience avec l'Esprit classique, pas d'Esprit V2. Je serais encore à attendre Esprit d'être fortement basée sur des modèles, mais maintenant, je suis juste deviner.

24voto

mmocny Points 3655

Dans boost 1.41 une nouvelle version de l'Esprit est d'être libéré, et il bat de pantalon large d'esprit::classique:

Après un long moment en version bêta (plus de 2 années avec l'Esprit 2.0), Esprit 2.1 sera finalement publié avec l' venir Stimuler 1.41 version. Le code est très stable et est maintenant prêt pour le code de production. Nous travaillons dur sur la finition de la documentation dans le temps pour Stimuler 1.41. Vous pouvez coup d'oeil à la état actuel de la documentation ici. Actuellement, vous pouvez trouver le code et de la documentation dans l'élan SVN le tronc. Si vous avez un nouveau projet de l'Esprit, nous recommandons fortement en commençant avec l'Esprit 2.1 maintenant. Permettez-moi pour citer OvermindDL de la poste à partir de la L'esprit de la liste de diffusion:

Je peut commencer à ressembler à un bot avec combien de fois je dis cela, mais Esprit.Classique, à l'ancienne, vous devriez interrupteur à Spirit2.1, il peut le faire tout ce que vous avez au-dessus d'une GRANDE plus facile, beaucoup moins de code, et il exécute plus rapidement. Par exemple, Spirit2.1 peut construire l'ensemble de votre AST en ligne, pas bizarre primordial, pas besoin pour construire des choses par la suite, etc..., tout comme l'un agréable et rapide étape. Vous vraiment besoin de mise à jour. Voir les autres les messages à partir de la dernière journée pour les liens docs et pour Spirit2.1. Spirit2.1 est actuellement en Boost Tronc, mais être officiellement sorti avec Boost 1.41, mais sinon complète.

19voto

marcin Points 1014

Pour moi, le plus gros problème est que les expressions dans Spirit, telles que vues par le compilateur ou le débogueur, sont plutôt longues (j'ai copié ci - dessous une partie d'une expression dans Spirit Classic). Ces expressions me font peur. Lorsque je travaille sur un programme qui utilise Spirit, j'ai peur d'utiliser valgrind ou d'imprimer backtrace dans gdb.

boost::spirit::classic::parser_result<boost::spirit::classic::action<boost::spirit::classic::sequence<boost::spirit::classic::action<boost::spirit::classic::action<optional_suffix_parser<char const*>, boost::spirit::classic::ref_actor<std::vector<std::string, std::allocator<std::string> >, boost::spirit::classic::clear_action> >, boost::spirit::classic::ref_actor<std::vector<int, std::allocator<int> >, boost::spirit::classic::clear_action> >, boost::spirit::classic::sequence<boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::action<boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::alternative<boost::spirit::classic::chlit<char>, boost::spirit::classic::chlit<char> >, boost::spirit::classic::positive<boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::alnum_parser, boost::spirit::classic::chlit<char> >, boost::spirit::classic::chlit<char> > > > >, boost::spirit::classic::ref_value_actor<std::vector<std::string, std::allocator<std::string> >, boost::spirit::classic::push_back_action> >, boost::spirit::classic::action<boost::spirit::classic::rule<boost::spirit::classic::scanner<char const*, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> >, boost::spirit::classic::nil_t, boost::spirit::classic::nil_t>, boost::spirit::classic::ref_const_ref_actor<std::vector<std::string, std::allocator<std::string> >, std::string, boost::spirit::classic::push_back_action> > >, boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::chlit<char>, boost::spirit::classic::action<boost::spirit::classic::uint_parser<unsigned int, 10, 1u, -1>, boost::spirit::classic::ref_value_actor<std::vector<int, std::allocator<int> >, boost::spirit::classic::push_back_action> > > > >, boost::spirit::classic::kleene_star<boost::spirit::classic::sequence<boost::spirit::classic::chlit<char>, boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::action<boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::alternative<boost::spirit::classic::chlit<char>, boost::spirit::classic::chlit<char> >, boost::spirit::classic::positive<boost::spirit::classic::alternative<boost::spirit::classic::alternative<boost::spirit::classic::alnum_parser, boost::spirit::classic::chlit<char> >, boost::spirit::classic::chlit<char> > > > >, boost::spirit::classic::ref_value_actor<std::vector<std::string, std::allocator<std::string> >, boost::spirit::classic::push_back_action> >, boost::spirit::classic::action<boost::spirit::classic::rule<boost::spirit::classic::scanner<char const*, boost::spirit::classic::scanner_policies<boost::spirit::classic::skipper_iteration_policy<boost::spirit::classic::iteration_policy>, boost::spirit::classic::match_policy, boost::spirit::classic::action_policy> >, boost::spirit::classic::nil_t, boost::spirit::classic::nil_t>, boost::spirit::classic::ref_const_ref_actor<std::vector<std::string, std::allocator<std::string> >, std::string, boost::spirit::classic::push_back_action> > >, boost::spirit::classic::contiguous<boost::spirit::classic::sequence<boost::spirit::classic::chlit<char>, boost::spirit::classic::action<boost::spirit::classic::uint_parser<unsigned int, 10, 1u, -1>, boost::spirit::classic::ref_value_actor<std::vector<int, std::allocator<int> >, boost::spirit::classic::push_back_action> > > > > > > > >, void (

14voto

user51568 Points 1519

Voici ce que je n'aime pas:

  • la documentation est limitée. Il y a une grande page web, où "tout" est expliqué, mais le manque d'explications en détails.

  • pauvres AST génération. ASTs sont mal expliquées et, même après frapper votre tête contre le mur, afin de comprendre comment l'AST modificateurs de travail, il est difficile d'obtenir un facile à manipuler AST (c'est à dire celui qui correspond bien du domaine du problème)

  • Il augmente les temps de compilation énormément, même pour la "moyenne"de la taille d'grammaires

  • La syntaxe est trop lourd. C'est un fait de la vie qu'en C/C++, vous devez dupliquer le code (c'est à dire entre la déclaration et la définition). Cependant, il semble que dans boost::spirit, lorsque vous déclarez une grammaire<>, vous devez répéter certaines choses 3 fois :D (quand vous voulez ASTs, qui est ce que je veux :D)

Autre que cela, je pense qu'ils ont fait un très bon travail avec l'analyseur, étant donné les limitations de C++. Mais je pense qu'ils devraient améliorer davantage. La page d'histoire décrit qu'il y avait une "dynamique" de l'esprit avant que le courant "statique" de l'esprit; je me demandais comment beaucoup plus vite et de la façon dont beaucoup mieux syntaxe qu'il avait.

3voto

Chris Dodd Points 1990

Je dirais que le plus gros problème est l’absence de diagnostic ou autre aide pour les problèmes de grammaire. Si votre grammaire est ambiguë, l’analyseur n’analysera peut-être pas ce que vous attendez, et il n’ya pas de bonne façon de le remarquer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X