Python 为什么pyparsing中的有序选择在我的用例中失败?
引发ParseException是否是因为Python 为什么pyparsing中的有序选择在我的用例中失败?,python,pyparsing,Python,Pyparsing,引发ParseException是否是因为scooby已在字符流中使用&因此解析器无法回溯?我正在寻找对此的详细实现说明 目前,我认为这是一个bug,因为解析器为什么不在匹配中短路,因为它没有搜索生产规则中的所有选择。 更新: 似乎MatchFirst并不完全等同于|运算符。为什么? MatchFirst(或“|”)通过设计实现短路。要强制检查所有备选方案,请使用或(或“^”)oneOf(“scooby scoobydoo”)也会起作用,因为oneOf会短路,但只有在重新排列有前导重叠的替代词之
scooby
已在字符流中使用&因此解析器无法回溯?我正在寻找对此的详细实现说明
目前,我认为这是一个bug,因为解析器为什么不在匹配中短路,因为它没有搜索生产规则中的所有选择。 更新:
似乎MatchFirst
并不完全等同于|
运算符。为什么?
MatchFirst
(或“|”)通过设计实现短路。要强制检查所有备选方案,请使用或(或“^”)oneOf(“scooby scoobydoo”)
也会起作用,因为oneOf
会短路,但只有在重新排列有前导重叠的替代词之后。Yes。我个人偏爱MatchFirst而不是Or,因此我努力使API保持简单,但在幕后确保进行匹配测试,以选择最长的匹配选项,不必评估所有可能的替代方案。我不理解您的更新-为什么您认为“|”和MatchFirst不同?“|”生成MatchFirst实例,“^”生成或实例。如果您对g
的定义重新排序,首先查找“scooby”,您将永远无法匹配“scoobydoo”。如果您保持顺序不变,但将“|”更改为“^”,则事情将再次正常运行;我更新的代码段显示,解析scooby
不会导致ParseException
,而它在我的原始代码段中却导致了。啊!您编写了MatchFirst(Literal(“scoobydoo”)、Literal(“scooby”))
——您应该编写的是MatchFirst([Literal(“scoobydoo”)、Literal(“scooby”)))
。MatchFirst最多需要2个参数,第一个是表达式列表,第二个是将数据保存为列表还是字符串的布尔标志。如果不将这两个文本包含在列表中,则只需使用Literal(“scoobydoo”)
构建MatchFirst,正如您所观察到的,它与“scooby”不匹配。
>>> g = MatchFirst( Literal("scoobydoo"), Literal("scooby") )
>>> g.parseString( "scooby" )
pyparsing.ParseException: Expected "scoobydoo" (at char 0), (line:1, col:1)
>>> g = Literal("scoobydoo") | Literal("scooby")
>>> g.parseString("scooby").asList()
['scooby']
>>> g.parseString("scoobydoo").asList()
['scoobydoo']