I'm trying the code sehe gave here : Boolean expression (grammar) parser in c++
I would like to create a string variable max, that would store the maximum variable encountered at each parsing (on the lexicographic order, for example).
I tried things like :
var_ = qi::lexeme[ +alpha ] [_val = _1, if_(phx::ref(m) < _1) [phx::ref(m) = _1]];
, but there is a (really long) compilation error
var_ = qi::lexeme[ +alpha [_val = _1, if_(phx::ref(m) < _1) [phx::ref(m) = _1]]];
but with this one I only get the first caracter of a variable, which is restrincting.
I also tried to simplify things using integers instead of string for variables, but var_ = int_ [...]
didn't work either, because int_ is already a parser (I think).
Do you have any ideas ?
Thanks in advance
I'd say that
start = *word [ if_(_1>_val) [_val=_1] ];
should be fine. However, due to a bug (?) Phoenix statements in a single-statement semantic action do not compile. You can easily work around it using a no-op statement, like e.g. _pass=true
in this context:
start = *word [ if_(_1>_val) [_val=_1], _pass = true ];
Now, for this I assumed a
rule<It, std::string()> word = +alpha;
If you insist you can cram it all into one rule though:
start = *as_string[lexeme[+alpha]] [ if_(_1>_val) [_val=_1], _pass = true ];
I don't recommend that.
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
template <typename It, typename Skipper>
struct max_parser : qi::grammar<It, std::string(), Skipper> {
max_parser() : max_parser::base_type(start) {
using namespace qi;
using phx::if_;
#if 1
word = lexeme [ +alpha ];
start = *word [ if_(_1>_val) [_val=_1], _pass = true ];
#else
start = *as_string[lexeme[+alpha]] [ if_(_1>_val) [_val=_1], _pass = true ];
#endif
}
private:
qi::rule<It, std::string(), Skipper> start, word;
};
int main() {
std::string const input("beauty shall be in ze eye of the beholder");
using It = std::string::const_iterator;
max_parser<It, qi::space_type> parser;
std::string data;
It it = input.begin(), end = input.end();
bool ok = qi::phrase_parse(it, end, parser, qi::space, data);
if (ok) {
std::cout << "Parse success: " << data << "\n";
} else {
std::cout << "Parse failed\n";
}
if (it != end)
std::cout << "Remaining unparsed: '" << std::string(it,end) << "'\n";
}
Prints:
Parse success: ze