gpt4 book ai didi

python - 如何打开 pyparsing 辅助函数的结果?

转载 作者:行者123 更新时间:2023-12-05 04:55:10 27 4
gpt4 key购买 nike

我目前正在用 python 实现 prolog 的方言。我正在使用美妙的 pyparsing用于此目的的模块,我发现它非常适用于涉及上下文无关语法的其他项目。

随着我转向上下文相关语法,我逐渐习惯了pyparsing 的风格。 pyparsing.nestedExprpyparsing.delimitedList 是我仍然熟悉的两件事。现在我遇到了 pyparsing.delimitedList 的问题;它实现了我正在寻找的东西,但下面示例代码中的每个单独的 term 都在列表中返回,我没有在任何条件下使用 pyparsing.Group

重构以使用 pyparsing.nestedExprpyparsing.infixNotation 是解决此问题后我的下一个待办事项,所以请不要因为我没有使用它们而 panic 然而。我还怀疑,但还不知道,我必须阻止匹配规则表达式左侧的 term_list。这就是说,该代码仍在进行中,随着我对库的进一步试验,它会随着时间的推移发生重大变化。

我觉得pyparsing.ungroup可以解决问题,但是pyparsing.ungroup(pyparsing.delimitedList...似乎没有任何作用这种情况。

输出逻辑

result = root.parseString('''
A :- True
Z :- 5
''')
print(result.dump())
print(result.rules[0].goals)

结果

[['A', 'True'], ['Z', '5']]
- rules: [['A', 'True'], ['Z', '5']]
[0]:
['A', 'True']
- goals: [['True']]
[0]:
['True']
[1]:
['Z', '5']
- goals: [['5']]
[0]:
['5']
[['True']]

预期结果

[['A', 'True'], ['Z', '5']]
- rules: [['A', 'True'], ['Z', '5']]
[0]:
['A', 'True']
- goals: ['True']
[1]:
['Z', '5']
- goals: ['5']
['True']

完整代码

import pyparsing as pp

# These types are the language primitives
atom = pp.Word(pp.alphanums)
number = pp.Word(pp.nums)
variable = pp.Word(pp.alphanums)
string = pp.quotedString

# Terms are the basic unit of expression here
compound_term = pp.Forward()
term = (atom ^ number ^ variable ^ pp.Group(compound_term))('terms*')

# A compound term includes a few rules for term composition, such as lists or an atom containing arguments
term_list = pp.Forward()
compound_term <<= \
string ^ \
term_list ^ \
atom('functor') + pp.Suppress('(') + pp.delimitedList(term('arguments*')) + pp.Suppress(')')

term_list <<= pp.Suppress('[') + pp.delimitedList(term('items*')) + pp.Suppress(']')

# The rule operator is an infix operator represented by :-
# On the right side, multiple goals can be composed using AND or OR operators
rule = pp.Group(
term + pp.Suppress(':-') + \
pp.delimitedList(term('goals*')) \
)('rules*')

root = pp.ZeroOrMore(rule)

result = root.parseString(
'''
A :- True
Z :- 5
''')
print(result.dump())
print(result.rules[0].goals)

最佳答案

最初的问题是 compound_term 中存在 Group:

term = (atom ^ number ^ variable ^ pp.Group(compound_term))('terms*')

应该是

term = (atom ^ number ^ variable ^ (compound_term))('terms*')

进行更改并在您的规则中添加“lhs”结果名称后(见下文),我明白了:

[['A', 'True'], ['Z', '5']]
- rules: [['A', 'True'], ['Z', '5']]
[0]:
['A', 'True']
- goals: ['True']
- lhs: 'A'
[1]:
['Z', '5']
- goals: ['5']
- lhs: 'Z'
['True']

一些补充说明:

  1. atom 定义为

    atom = pp.Word(pp.alphanums)

    这也将作为 atom 匹配“123”。为确保您只获得变量 names ,请使用 pp.Word(pp.alphas, pp.alphanums)。这表示首字母必须是字母,任何后续字母都可以是字母或数字(与 variable 相同)。

  2. 我不会在术语上添加结果名称“terms*”,因为它最终会在“:-”运算符的左右两侧使用。我建议人们通常 保留结果名称的附件,直到在更高级别的表达式中使用该表达式。例如,我会将规则定义为:

    rule = pp.Group(term("rule_lhs") 
    + ":-"
    + pp.delimitedList(term)("goals")
    )
  3. 我不会真正称“:-”为“中缀”运算符,我将“+”、“-”、“AND”、“OR”等运算符视为中缀运算符。例如,我认为 x :- y :- z 是无效的。您可能会执行类似这样的操作来添加“AND”和“OR”运算符:

    logical_term_expression = pp.infixNotation(term,
    [
    ("&&", 2, pp.opAssoc.LEFT,),
    ("||", 2, pp.opAssoc.LEFT,),
    ])

    term 中有一个结果名称真的会把事情搞得一团糟,更有可能在你的运算符元组上使用类,正如你在像 simple_bool.py 这样的 pyparsing 例子中看到的。

  4. 您提到使用 nestedExpr - 请不要这样做。该助手最适用于为 C 代码之类的东西编写扫描器,在这种情况下您可能只想跳过一些嵌套的大括号而不实际解析内容。在您的 DSL 中,您会希望正确解析所有内容 - 但我认为 infixNotation 可能就是您所需要的。

关于python - 如何打开 pyparsing 辅助函数的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65534745/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com