Представьте себе следующие типы строк:
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)
но безрезультатно, правда (факторы дублируются в двух экземплярах).
Примечание: Этот вопрос основан на еще одном в StackOverflow.