c++ - spirit x3: locally defined rule definition must have an attribute attached? -


simple x3 code cannot compile because nothing attached 2nd ruletest or whole parser. if put x3::omit[ruletest] around second ruletest still cannot compile.

void test(std::string const& str) {     auto const ruletest = x3::rule<struct _, std::string>{} =         *(x3::char_ - ' ')[([](auto& ctx){x3::_val(ctx)+='x';})];     x3::parse(boost::begin(str), boost::end(str),          ruletest[([](auto& ctx){std::cout<<x3::_attr(ctx)<<std::endl;})] >>         ' ' >>         ruletest     ); }  

only when attach lambda or attribute x3::parse or define ruletest globally boost_spirit_define solve problem.

void test(std::string const& str) {     auto const ruletest = x3::rule<struct _, std::string>{} =         *(x3::char_ - ' ')[([](auto& ctx){x3::_val(ctx)+='x';})];     std::string attr;     x3::parse(boost::begin(str), boost::end(str),          ruletest[([](auto& ctx){std::cout<<x3::_attr(ctx)<<std::endl;})] >>         ' ' >>         ruletest, attr); } 

the crux of error appears be

test.cpp|9 col 59| error: no match ‘operator+=’ (operand types ‘boost::spirit::x3::unused_type’ , ‘char’) 

this because compiler sees actual type of bound attribute (none) x3::unused_type , therefore semantic action doesn't compile.

i'm not sure how want work since cannot update characters 'x' in attribute doesn't exist.

here's proposed "fix":

struct {      void operator()(std::string& s, char c) const { s += c; }     void operator()(...)                    const { } } ll;  auto const ruletest      = x3::rule<struct _, std::string>{}      = *(x3::char_ - ' ') [([ll](auto& ctx){ ll(x3::_val(ctx), 'x');})]     ; 

see live on coliru

#include <boost/spirit/home/x3.hpp> #include <iostream>  void test(std::string const& str) {     namespace x3 = boost::spirit::x3;      struct {          void operator()(std::string& s, char c) const { s += c; }         void operator()(...)                    const { }     } ll;      auto const ruletest          = x3::rule<struct _, std::string>{}          = *(x3::char_ - ' ') [([ll](auto& ctx){ ll(x3::_val(ctx), 'x');})]         ;      //std::string attr;     auto f = begin(str), l = end(str);     bool ok = x3::parse(f, l,              ruletest [([](auto& ctx){std::cout<<x3::_attr(ctx)<<std::endl;})]              >> ' ' >> ruletest);      if (ok)     std::cout << "parse success\n";     else        std::cout << "parse failed\n";     if (f != l) std::cout << "remaining unparsed: '" << std::string(f,l) << "'\n"; }  int main() {     test("abc def"); } 

Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -