Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost Spirit Qi解析器不使用整个字符串表达式吗?_C++_Parsing_Boost_Boost Spirit - Fatal编程技术网

C++ Boost Spirit Qi解析器不使用整个字符串表达式吗?

C++ Boost Spirit Qi解析器不使用整个字符串表达式吗?,c++,parsing,boost,boost-spirit,C++,Parsing,Boost,Boost Spirit,假设我有以下规则: 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 %= 
        lexeme[
            char_("a-zA-Z")
            >> -(*char_("a-zA-Z_0-9")
            >> char_("a-zA-Z0-9"))
        ]
        ;

qi::rule<Iterator, std::string(), Skipper> 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>

这是有效的123
这是有效的123
这是有效的123
这是有效的123
他的身份证是有效的
[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]]
他的身份证是有效的
他的身份证是有效的
他的身份证是有效的

我已经尝试在词素表达式中使用as_字符串,但没有任何帮助。

我不明白为什么要使表达式复杂化。你能试试吗

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

qi::rule<Iterator, std::string()> identifier;
identifier%=
char_uuz(“a-zA-Z”)
>>*字符(“a-zA-Z_0-9”)
;
qi::规则标识符;
这是你能得到的最标准的表达式。即使您不想允许标识符以
\uu
结尾,我很确定您也不希望这样一个尾随
\u
被解析为“下一个标记”。在这种情况下,我只需在解析之后添加验证

更新评论内容

以下是分析:

  • 首先:
    -(*x)
    是一个红旗。它从来都不是一个有用的模式,因为
    *x
    已经匹配了一个空序列,您不能将其设置为“更可选”

    (事实上,如果
    *x
    像在正则表达式中一样允许部分回溯,那么您可能已经看到了指数级的性能,甚至是infite运行时;“幸运的是,
    *x
    总是贪婪的)

这确实促进了您的bug。让我们看看OP中的解析器表达式,如第1、2、3行

  • 首先,第1行匹配
    T
  • 第二行最初贪婪地匹配
    他的\u是\u有效的123 \u标识符
  • 但是这不能满足第三行的要求,所以
    -(…)
    开始,第1行之后的所有内容都被回溯
  • 然而:齐

    • 确实回溯游标(当前输入迭代器),但
    • 默认情况下不会回滚对容器属性的更改
    对。你猜对了<代码>标准::字符串是一个容器属性

因此,最终的结果是长度为1的成功匹配,以及属性中失败可选序列的剩余值

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


    • 我不明白你为什么要把这个表达复杂化。你能试试吗

      identifier %= 
                      char_("a-zA-Z")
                  >> *char_("a-zA-Z_0-9")
              ;
      
      qi::rule<Iterator, std::string()> identifier;
      
      identifier%=
      char_uuz(“a-zA-Z”)
      >>*字符(“a-zA-Z_0-9”)
      ;
      qi::规则标识符;
      
      这是你能得到的最标准的表达式。即使您不想允许标识符以
      \uu
      结尾,我很确定您也不希望这样一个尾随
      \u
      被解析为“下一个标记”。在这种情况下,我只需在解析之后添加验证

      更新评论内容

      以下是分析:

      • 首先:
        -(*x)
        是一个红旗。它从来都不是一个有用的模式,因为
        *x
        已经匹配了一个空序列,您不能将其设置为“更可选”

        (事实上,如果
        *x
        像在正则表达式中一样允许部分回溯,那么您可能已经看到了指数级的性能,甚至是infite运行时;“幸运的是,
        *x
        总是贪婪的)

      这确实促进了您的bug。让我们看看OP中的解析器表达式,如第1、2、3行

      • 首先,第1行匹配
        T
      • 第二行最初贪婪地匹配
        他的\u是\u有效的123 \u标识符
      • 但是这不能满足第三行的要求,所以
        -(…)
        开始,第1行之后的所有内容都被回溯
      • 然而:齐

        • 确实回溯游标(当前输入迭代器),但
        • 默认情况下不会回滚对容器属性的更改
        对。你猜对了<代码>标准::字符串是一个容器属性

      因此,最终的结果是长度为1的成功匹配,以及属性中失败可选序列的剩余值

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


      为什么不能使用我发布的解析器呢?老实说,我还没有看过。我有向目标推理的习惯。“有机生长”的解析器表达式甚至可能不完整,关于它们的推理是。。。很难。但是,请参见更新的答案。干杯。这应该被标记为答案!这是一个很好的解释!!为什么不能使用我发布的解析器呢?老实说,我还没看过。我有向目标推理的习惯。“有机生长”的解析器表达式甚至可能不完整,关于它们的推理是。。。很难。但是,请参见更新的答案。干杯。这应该被标记为答案!这是一个很好的解释!!