Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 like 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.

like image 595
Ylisar Avatar asked Nov 05 '22 01:11

Ylisar


1 Answers

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.

like image 179
hkaiser Avatar answered Nov 12 '22 19:11

hkaiser