2

我很难理解为什么以下解析器无法解析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,而是字符串的其余部分。

4

1 回答 1

2

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

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

这行得通。

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

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

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

  1. 我已经包含了存储双精度值的语义动作。它将它存储在一个名为mynr.
  2. 我已经包裹*alnum在一个lexeme. 这会导致解析器在内部不跳过任何字符。
  3. 有了这个正确的语法,它就能够解析"#define SOMEMACRO 8.0""#define SOMEMACRO 8"
于 2013-03-22T15:10:11.847 回答