Minimizing boost::spirit compile times

僤鯓⒐⒋嵵緔 提交于 2019-12-02 16:17:45

One trick I could suggest is to separate the compilation of the constructors of both, your lexer and your grammar. The easiest way to achieve this is to leave only the declaration of those constructors in their respecitive header files and to move the definition of those functions into separate translation units. For instance:

grammar.hpp:

template <typename Iterator>
struct grammar : qi::grammar<Iterator>
{
    grammar();   // declaration only
    // ...
};

grammar_def.hpp:

// This file should not contain anything else.
#include "grammar.hpp"

// Definition of constructor.
template <typename Iterator>
grammar<Iterator>::grammar()
{
    // initialize your rules here
}

grammar.cpp:

// This file should not contain anything else.
#include "grammar_def.hpp"

// Explicitly instantiate the constructor for the iterator type
// you use to invoke the grammar (here, as an example I use 
// std::string::const_iterator).
typedef std::string::const_iterator iterator_type;
template grammar<iterator_type>::grammar();

Do the same thing for the lexer object.

This approach requires a bit more work than the straight method, but it allows to distribute the memory and time requirements for the overall compilation. Another advantage of this approach is that any change in the grammar constructor does not require the recompilation of anything except the file grammar.cpp.

Another advice for the lexer: try to minimize the use of token_def<> instances as much as possible. You need to use token_def<> only when you want to access the token value as an attribute during parsing. In all other cases you might get away with lex::string or lex::char_ to define your tokens.

ravenspoint

I have to come to the conclusion that boost:spirit, elegant as it is, is not a viable option for many real world parsing problems due to the lengthy compile times that even experts cannot fix.

It is often best to stick to something like flex, which may be ugly and old-fashioned, but is relatively simple and lightning fast.

As an example of what I consider a 'real world' problem here is the railroad diagram of the most important part of a parser that flex compiles in a couple of seconds, but boost:spirit is still chugging away on after ten minutes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!