2

我有以下简单的语法:

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:dataand之类的字符串noprefix。在第一种情况下(“前缀:数据”),使用上述语法,我希望my_attr填充两个成员,并且这可以按预期工作。

但在第二种情况下(“noprefix”),我希望只my_attr.second填充。但是,我看到两者firstsecond填充了相同的数据,即“noprefix”。这是它应该如何工作的吗?行为不直观。

完整来源:

#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;
}
4

0 回答 0