Using a pointer to a parser in boost::spirit
Basically I'm doing an expression parser. As I'm in need of as good as possible performance, and according to the documentation construction of a grammar can be rather slow, I'd lik开发者_运维知识库e to reuse the grammar and bind the symbol table just before parsing. As the client of the grammar is likely to have a symbol table that's constructed and maintained ahead of parsing, I'd ideally like to avoid copying of the actual table as well which leads me to the following code ( simplified ) for translating terms:
qi::symbols< char, double >* m_Symbols;
qi::rule< Iterator, double(), ascii::space_type > m_Val;
m_Val = qi::int_[ _val = boost::phoenix::static_cast_< double >( boost::spirit::_1 ) ] | qi::double_ | m_Symbols;
The problem here is m_Symbols. What I'd like is to m_Val to hold m_Symbols by reference, as when we're binding the symbol table I'm naturally modifying the pointer, which I presume can somehow be solved by the use of boost::phoenix::ref? But the larger problem is that I can't seem to use pointer to parsers when compositing new parser. Using dereference in the expression dereferences m_Symbols straight away, which is unwanted, I want to delay the dereferencing to parse time.
I believe a simple
qi::symbols<char, double>* m_Symbols;
qi::rule<Iterator, double(), ascii::space_type> m_Val;
m_Val = qi::int_ | qi::double_ | qi::lazy(*m_Symbols);
should do what you need. The lazy
parser (see here) evaluates its argument (repeatedly) at parse time only.
精彩评论