【问题标题】:Boost Spirit Qi parser does not consume whole string expression?Boost Spirit Qi解析器不消耗整个字符串表达式?
【发布时间】:2014-03-25 15:11:43
【问题描述】:

假设我有以下规则:

identifier %= 
        lexeme[
            char_("a-zA-Z")
            >> -(*char_("a-zA-Z_0-9")
            >> char_("a-zA-Z0-9"))
        ]
        ;

qi::rule<Iterator, std::string(), Skipper> identifier;

以及以下输入:

// identifier
This_is_a_valid123_Identifier

正如跟踪显示的那样,标识符已正确解析并设置了属性,但船长再次在字符串的第一个字符之后开始一个字符:

<identifier>
  <try>This_is_a_valid123_I</try>
  <skip>
    <try>This_is_a_valid123_I</try>
    <emptylines>
      <try>This_is_a_valid123_I</try>
      <fail/>
    </emptylines>
    <comment>
      <try>This_is_a_valid123_I</try>
      <fail/>
    </comment>
    <fail/>
  </skip>
  <success>his_is_a_valid123_Id</success>
  <attributes>[[T, h, i, s, _, i, s, _, a, _, v, a, l, i, d, 1, 2, 3, _, I, d, e, n, t, i, f, i, e, r]]</attributes>
</identifier>
<skip>
  <try>his_is_a_valid123_Id</try>
  <emptylines>
    <try>his_is_a_valid123_Id</try>
    <fail/>
  </emptylines>
  <comment>
    <try>his_is_a_valid123_Id</try>
    <fail/>
  </comment>
  <fail/>
</skip>

我已经尝试在词位表达式中使用 as_string,但没有帮助。

【问题讨论】:

    标签: c++ parsing boost boost-spirit


    【解决方案1】:

    我不明白你为什么要把表达复杂化。可以试试吗

    identifier %= 
                    char_("a-zA-Z")
                >> *char_("a-zA-Z_0-9")
            ;
    
    qi::rule<Iterator, std::string()> identifier;
    

    这是你能得到的最标准的表达方式。即使您不想允许以 _ 结尾的标识符,我也很确定您不希望将这样的尾随 _ 解析为“下一个令牌”。在这种情况下,我只需在解析后添加验证即可。

    更新评论:

    分析如下:

    • 首先:-(*x) 是一个危险信号。它从来都不是一个有用的模式,因为*x 已经匹配一个空序列,你不能让它“更可选”

      (事实上,如果 *x 像正则表达式一样允许部分回溯,您可能会看到指数性能甚至无限运行时间;“幸运的是”,*x 在 Spirit 中总是贪婪的齐).

    这确实有助于您的错误。让我们看看你在 OP 中的解析器表达式为第 1、2、3 行。

    • 首先,第 1 行匹配 T
    • 第二行最初贪婪地匹配his_is_a_valid123_Identifier
    • 但这不能满足第三行,所以-(...) 开始,第1 行之后的所有内容都被回溯。
    • 然而:齐

      • 确实回溯 游标(当前输入迭代器)但
      • 默认回滚对容器属性的更改。

      是的。你猜对了。 std::string 是一个容器属性。

    所以你最终得到的是长度为 1 的成功匹配和属性中失败的可选序列的残差。

    其他一些关于如何解决这种回溯问题的背景资料:

    【讨论】:

    • 为什么不能使用我发布的解析器?
    • 老实说,我没看过。我习惯于对目标进行推理。 “有机增长”的解析器表达式甚至可能不完整,并且对它们进行推理......很难。但是,请参阅 更新 答案。干杯。
    • 这应该被标记为答案!这是一个很好的解释!
    猜你喜欢
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多