【问题标题】:Recursive parsing for lisp like syntax类似lisp的语法的递归解析
【发布时间】:2013-03-18 18:18:55
【问题描述】:

我正在尝试解析表单中的行:

(OP something something (OP something something ) ) ( OP something something )

其中 OP 是逻辑门(AND、OR、NOT)的符号,而某些东西是我想要评估的东西。

我正在寻找的输出类似于:

{ 'OPERATOR': [condition1, condition2, .. , conditionN] }

条件本身可以是字典/列表对本身(嵌套条件)。到目前为止,我尝试了类似的方法:

        tree = dict()
        cond = list()
        tree[OP] = cond


    for string in conditions:
        self.counter += 1
        if string.startswith('('):
            try:
                OP = string[1]
            except IndexError:
                OP = 'AND'
            finally:
                if OP == '?':
                    OP = 'OR'
                elif OP == '!':
                    OP = 'N'

            # Recurse
            cond.append(self.parse_conditions(conditions[self.counter:], OP))
            break

        elif not string.endswith(")"):
            cond.append(string)

        else:
            return tree

    return tree

我也尝试了其他方法,但我无法理解整个递归问题,所以我想知道我是否可以在这里得到一些指示,我环顾网络,发现了一些关于递归下降解析的东西,但是教程都在尝试做一些比我需要的更复杂的事情。

PS:我意识到我可以使用现有的 python 库来做到这一点,但是这样做我能学到什么嗯?

【问题讨论】:

  • 是实际的recursion 你理解有问题,还是recursive descent parser 的工作原理?
  • 如果 '(' 后面有空格怎么办?不要试图重新发明自行车,学习code.google.com/p/funcparserlibpyparsing.wikispaces.com 这样干净整洁的库
  • @JoachimPileborg 我猜它是整个递归的事情,我就是做错了。
  • @SK-logic 我已经处理好了,我不想重新发明轮子我想学习。
  • 你学错了。像您这样的临时解决方案不会教给您任何有用的东西。您最好立即学习正确的方法,正确的方法是使用组合器。它也更容易理解、更简洁、更灵活。因此,如果您想学习,请开始编写自己的组合器库。

标签: python string parsing recursion recursive-descent


【解决方案1】:

出于学习目的(在现实生活中请务必使用图书馆),我将在没有进一步 cmets 的情况下发布此内容。请注意,没有错误检查(你的功课!)

如果有什么不明白的欢迎随时提问。

# PART 1. The Lexer

symbols = None

def read(input):
    global symbols
    import re
    symbols = re.findall(r'\w+|[()]', input)

def getsym():
    global symbols
    return symbols[0] if symbols else None

def popsym():
    global symbols
    return symbols.pop(0)

# PART 2. The Parser
# Built upon the following grammar:
#  
#     program = expr*
#     expr    = '(' func args ')'
#     func    = AND|OR|NOT
#     args    = arg*
#     arg     = string|expr
#     string  = [a..z]

def program():
    r = []
    while getsym():
        r.append(expr())
    return r

def expr():
    popsym() # (
    f = func()
    a = args()
    popsym() # )
    return {f: a}

def func():
    return popsym()

def args():
    r = []
    while getsym() != ')':
        r.append(arg())
    return r

def arg():
    if getsym() == '(':
        return expr()
    return string()

def string():
    return popsym()

# TEST = Lexer + Parser

def parse(input):
    read(input)
    return program()

print parse('(AND a b (OR c d)) (NOT foo) (AND (OR x y))')
# [{'AND': ['a', 'b', {'OR': ['c', 'd']}]}, {'NOT': ['foo']}, {'AND': [{'OR': ['x', 'y']}]}]

【讨论】:

  • 谢谢。这正是我需要的。我仍然需要弄清楚它是如何做到的,但是你的代码会很有帮助,所以谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多