我有以下简单的语法:
namespace parser {
using x3::lexeme;
using x3::lit;
using x3::ascii::char_;
using my_attr = std::pair<boost::optional<std::string>, std::string>;
x3::rule<class ncname_tok, std::string> ncname = "ncname-token";
x3::rule<class qname_tok, my_attr> qname = "qname";
auto ncname_def = lexeme[*(char_ - ':')];
auto qname_def = -( ncname >> ':' ) >> ncname;
BOOST_SPIRIT_DEFINE (ncname, qname);
}
期望是解析prefix:data
和noprefix
等字符串。在第一种情况下(&#34;前缀:数据&#34;),使用上述语法,我期望填充my_attr
的两个成员,并且这可以按预期工作。
但在第二种情况下(&#34; noprefix&#34;),我希望只填充my_attr.second
。但是,我发现first
和second
都填充了相同的数据,即&#34; noprefix&#34;。它应该如何工作?行为不直观。
完整来源:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace x3 = boost::spirit::x3;
namespace parser {
using x3::lexeme;
using x3::lit;
using x3::ascii::char_;
using my_attr = std::pair<boost::optional<std::string>, std::string>;
x3::rule<class ncname_tok, std::string> ncname = "ncname-token";
x3::rule<class qname_tok, my_attr> qname = "qname";
auto ncname_def = lexeme[*(char_ - ':')];
auto qname_def = -( ncname >> ':' ) >> ncname;
BOOST_SPIRIT_DEFINE (ncname, qname);
}
int main() {
std::string input("just-go");
std::string::iterator strbegin = input.begin();
parser::my_attr p;
x3::parse(strbegin, input.end(),
parser::qname,
p);
if (p.first) {
std::cout << "There should be no prefix: " << p.first << std::endl;
}
std::cout << "local name: " << p.second << std::endl;
return 0;
}