简单的x3代码无法编译,因为没有任何内容附加到第二个ruleTest或整个解析器。即使我们将x3::omit[ruleTest]
放在第二个ruleTest
附近,它仍然无法编译。
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
);
}
只有当我们将一个lambda或一个属性附加到x3 :: parse或用BOOST_SPIRIT_DEFINE全局定义ruleTest时才能解决问题。
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);
}
答案 0 :(得分:1)
错误的症结似乎是
test.cpp|9 col 59| error: no match for ‘operator+=’ (operand types are ‘boost::spirit::x3::unused_type’ and ‘char’)
这是因为编译器看到绑定属性的实际类型(none)是x3::unused_type
,因此语义操作不会编译。
我甚至不确定您希望它如何工作,因为您无法在不存在的属性中将字符更新为'x'
。
这是一个提议的“修复”:
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');})]
;
#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");
}