【问题标题】:Parsing expressions with suffixes using pyparsing使用 pyparsing 解析带后缀的表达式
【发布时间】:2020-02-14 23:25:28
【问题描述】:

我想使用 PyParsing 解析以下(简化的)递归表达式:

foo
(foo + bar)
foo'attribute
foo + bar'attribute
foo.field
(foo'attribute + foo.field)'attribute

我想出了以下适用于上述所有表达式的解析器:

        identifier = Word(alphas)
        expr = (
            infixNotation(
                identifier,
                [
                    (Literal(".") + identifier, 1, opAssoc.LEFT),
                    (Literal("'") + identifier, 1, opAssoc.LEFT),
                    (Literal("+"), 2, opAssoc.LEFT),
                ],
            )
            + StringEnd()
        )

然而,失败的是包含.field'attribute 后缀的表达式。虽然foo.field'attribute 被接受,但foo'attribute.field 产生

pyparsing.ParseException: Expected end of text (at char 13), (line:1, col:14)

当为infixNotationattributefield 交换元组时,第二个表达式解析而第一个表达式不解析。似乎顺序/优先级是相关的。

任何想法如何解析不同后缀的任意递归外观?

【问题讨论】:

  • 有趣地使用一元运算符来限制第二个操作数的形式。我原本打算建议制作这些二元运算符,但是在.' 分隔符之后可能会有无效的表达式。很酷!
  • @PaulMcG 谢谢!并且特别感谢制作 pyparsing - 这个库在过去的许多项目中为我提供了很好的服务!

标签: python pyparsing


【解决方案1】:

列表中的每个元组都定义了自己的优先级。当一个运算符的优先级高于另一个运算符时,低优先级运算符只能通过括号用作高优先级运算符的操作数(注意(foo'attribute).field 解析得很好)。

对于一元运算符,您通常希望所有后缀运算符都有一个优先级(如果有的话,所有前缀运算符都需要另一个优先级)。在 pyparsing 中执行此操作的方式是使用包含可以匹配两个运算符的单个规则的元组:

(oneOf(". '") + identifier, 1, opAssoc.LEFT),

【讨论】:

  • Literal("X") | Literal("Y") | Literal("Z") 的快捷方式是oneOf("X Y Z")。我本来建议改为使用这些二元运算符,但我认为您想将第二个操作数限制为仅作为标识符,因此 OP 使用的新颖的一元方法将起作用。
  • @PaulMcG 谢谢,我改了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多