gpt4 book ai didi

python - Python 中用于 PEG 解析器的 NodeVisitor 类

转载 作者:太空宇宙 更新时间:2023-11-03 15:34:57 25 4
gpt4 key购买 nike

想象一下以下类型的字符串:

if ((a1 and b) or (a2 and c)) or (c and d) or (e and f)

现在,我想得到括号中的表达式,所以我用以下语法编写了一个 PEG 解析器:

from parsimonious.grammar import Grammar

grammar = Grammar(
r"""
program = if expr+
expr = term (operator term)*
term = (factor operator factor) / factor
factor = (lpar word operator word rpar) / (lpar expr rpar)

if = "if" ws
and = "and"
or = "or"
operator = ws? (and / or) ws?

word = ~"\w+"
lpar = "("
rpar = ")"

ws = ~"\s*"
""")

解析得很好

tree = grammar.parse(string)

现在问题来了:如何为这棵树编写一个 NodeVisitor 类来只获取因子?我的问题是第二个分支可以深度嵌套。


我试过

def walk(node, level = 0):
if node.expr.name == "factor":
print(level * "-", node.text)

for child in node.children:
walk(child, level + 1)

walk(tree)

但实际上无济于事(因素重复出现)。
注意:此问题基于 another one在 StackOverflow 上。

最佳答案

How would I go about it to get ((a1 and b) or (a2 and c)), (c and d) and (e and f) as three parts?

您可以创建一个访问者,当解析树中的节点是 (,其中增加了深度变量,并且当 ) 时“监听”遇到时,深度变量减小。然后在调用的匹配括号表达式的方法中,检查深度,然后将其添加到要从访问者返回的表达式列表中。

这是一个简单的例子:

from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor

grammar = Grammar(
r"""
program = if expr+
expr = term (operator term)*
term = (lpar expr rpar) / word

if = "if" ws
and = "and"
or = "or"
operator = ws? (and / or) ws?

word = ~"\w+"
lpar = "("
rpar = ")"

ws = ~"\s*"
""")


class ParExprVisitor(NodeVisitor):

def __init__(self):
self.depth = 0
self.par_expr = []

def visit_term(self, node, visited_children):
if self.depth == 0:
self.par_expr.append(node.text)

def visit_lpar(self, node, visited_children):
self.depth += 1

def visit_rpar(self, node, visited_children):
self.depth -= 1

def generic_visit(self, node, visited_children):
return self.par_expr


tree = grammar.parse("if ((a1 and b) or (a2 and c)) or (c and d) or (e and f)")
visitor = ParExprVisitor()

for expr in visitor.visit(tree):
print(expr)

打印:

((a1 and b) or (a2 and c))
(c and d)
(e and f)

关于python - Python 中用于 PEG 解析器的 NodeVisitor 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55405055/

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