Boost.Spirit解析器不匹配

时间:2013-03-22 14:56:44

标签: c++ boost boost-spirit boost-spirit-qi

我很难理解为什么以下解析器无法解析test。 致电qi::phrase_parse后,result为真,it2指向字符串末尾,但mynr仍为0:

std::string test = "#define   SOMEMACRO 8.0";
  auto it2 = test.begin();
  auto endIt2 = test.end();
  double mynr = 0;
  bool result = 
    qi::phrase_parse(
      it2, 
      endIt2, 
      ("#define" >> (*qi::alnum) >> qi::double_[ref(mynr) = qi::_1]), 
      qi::space);

我怀疑它与qi::alnum和空间跳过有关。

我尝试将我的案例简化为单个组件。我分别验证了这三个解析器并发现:

  • “#define”确实消耗“#define”
  • (*qi::alnum)可以使用SOMEMACRO
  • qi::double_可以使用8.0

另外,每个解析器工作正常,但是在上面的表单中拼凑起来很奇怪。进一步的小测试似乎向我表明(*qi::alnum)当我使用它时,它似乎消耗的不仅仅是SOMEMACRO,而是字符串的其余部分。

1 个答案:

答案 0 :(得分:2)

您的更新实际上让我意识到发生了什么。你是对的,*alnum吃得比你想要的多。

("#define" >> lexeme[*qi::alnum] >> (qi::double_)[boost::phoenix::ref(mynr) = boost::spirit::_1])

这很有效。

*alnum正在吃字母数字字符,并在它们之间跳过空格。所以它实际上吃了SOMEMACRO 8。然后,当我在最后吃8.0时建议它有效时,那是因为双解析器消耗了.0

顶部的新解析器要求*alnum中间没有空格。

以下是关于语法的新注意事项:

  1. 我已经包含了语义操作来存储double的值。它将它存储在一个名为mynr的双重中。
  2. 我已将*alnum包裹在lexeme中。这会导致解析器在内部不跳过任何字符。
  3. 使用正确的语法,它可以解析"#define SOMEMACRO 8.0""#define SOMEMACRO 8"