Pyparsing getName() returns 错误的名字

Pyparsing getName() returns wrong name

我正在使用 dotted.strings 和中缀数学运算符解析字符串。解析本身似乎工作正常,但 getName 编辑的名称 return 并不是我所期望的。

from pyparsing import (Word, alphas, opAssoc, infixNotation, 
                       Suppress, Group, delimitedList, oneOf)
LPAR, RPAR = map(Suppress, "()")

chars = Word(alphas + "_")
colstr = Group(delimitedList(chars, delim=".")).setResultsName("colstr*")
infix_expr = infixNotation(colstr, [
    ("-", 1, opAssoc.RIGHT),
    (oneOf("* /"), 2, opAssoc.LEFT),
    (oneOf("+ -"), 2, opAssoc.LEFT),
])("infix")

现在正在测试...

>>> infix_ex = infix_expr.parseString('a.b + x.y')
>>> print(infix_ex.dump())
[[['a', 'b'], '+', ['x', 'y']]]
- infix: [['a', 'b'], '+', ['x', 'y']]
  - colstr: [['a', 'b'], ['x', 'y']]
    [0]:
      ['a', 'b']
    [1]:
      ['x', 'y']

这是我所期望的,但是 getName 似乎 return 来自错误的解析树级别的名称。

>>> infix_ex.getName()
'infix'
>>> infix_ex[0].getName()
'colstr'
>>> infix_ex[0].asList()
[['a', 'b'], '+', ['x', 'y']]

如您所见,getName returns 'infix' 表示根级别,'colstr' 表示树的 'infix' 级别。

这几乎是不可避免的,因为 getName() 是在 ParseResults 上定义的方法,而不是在匹配的标记上定义的(它可能是一个字符串,因此不支持 getName()).

这是来自 ParseResults.getName 文档字符串的示例:

    integer = Word(nums)
    ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
    house_number_expr = Suppress('#') + Word(nums, alphanums)
    user_data = (Group(house_number_expr)("house_number")
                | Group(ssn_expr)("ssn")
                | Group(integer)("age"))
    user_info = OneOrMore(user_data)

    result = user_info.parseString("22 111-22-3333 #221B")
    print(result.asList())
    for item in result:
        print(item.getName(), ':', item[0])

打印:

[['22'], ['111-22-3333'], ['221B']]
age : 22
ssn : 111-22-3333
house_number : 221B

请注意,要使用 getName(),每个命名位都必须是 Group,并且名称在容器上,而不是直接在匹配的令牌上。

可以在非 Group 元素上定义结果名称,并直接访问它们而无需获取第 [0] 个元素,但是你将无法对他们调用 getName()

如果您计划使用 getName() 遍历使用 infixNotation 解析返回的结构,我鼓励您改为为操作数和每个操作数定义自己的容器 类中缀符号语法中的优先级。请参阅 simple_bool.py 示例代码以了解这是如何完成的。这样你就可以更直接地控制从 pyparsing 传回给你的对象,而不是试图通过解析的中缀符号层次结构(可能 re-trace 过程中的一些解析步骤)。