Python 解析嵌套模板

Python 解析嵌套模板,python,Python,下面的代码将把用括号(模板分隔符)标记的模板(作为测试的字符)转换为扩展形式。每个模板都通过调用单独的函数(handle())进行处理,并且转换只能发生一次。可以存在嵌套模板,解析器应该检测到这一点。在某些情况下,处理程序无法展开未知模板,并将在其分隔符中返回未触及的模板(以便稍后更新处理程序时进行进一步处理) 下面发布的代码在很大程度上起作用。它唯一没有通过的测试用例是带有两个嵌套未知模板的输入 我已经求助于一些乱七八糟的东西来实现这一点,我想知道是否还有更好的东西(可能是Python库?)。

下面的代码将把用括号(模板分隔符)标记的模板(作为测试的字符)转换为扩展形式。每个模板都通过调用单独的函数(
handle()
)进行处理,并且转换只能发生一次。可以存在嵌套模板,解析器应该检测到这一点。在某些情况下,处理程序无法展开未知模板,并将在其分隔符中返回未触及的模板(以便稍后更新处理程序时进行进一步处理)

下面发布的代码在很大程度上起作用。它唯一没有通过的测试用例是带有两个嵌套未知模板的输入

我已经求助于一些乱七八糟的东西来实现这一点,我想知道是否还有更好的东西(可能是Python库?)。特别是,代码需要以相反顺序(基于堆栈)连接结果,并标记已使用不同运算符处理的项。最后,我不得不使用
join()
作为结果,因为解析器在相同级别的括号之间拆分

更新

更多用例来阐明如何使用代码

def parse(tokens):
    operStack = list()
    exprStack = list()

    for c in tokens:
        if c.isalpha():
            exprStack.append(c)
            operStack.append("+")

        elif c == '(':
            operStack.append(c)

        elif c == ")":
            concat = ""
            while operStack[-1] != '(':
                operator = operStack.pop()
                c = exprStack.pop()
                if operator == "+":
                    c = handle(c)
                concat = c + concat  # reverse

            operStack.pop()  # discard '('

            exprStack.append(concat)
            operStack.append("-")  # mark item

        else:
            raise RuntimeError()  # should never come here.

    return "".join(exprStack)


def handle(letter):
    letters = dict (a="Apple", b="Banana", c="Car", d="Dog", e="Elephant")

    try:
        word = letters[letter]  # found a match, substitute letter for word
        return " %s " % word
    except KeyError:
        return "(%s)" % letter  # unhandled case, return the letter


def check(actual, expected):
    print("SUCCESS" if actual == expected else "FAILED: got '%s', expected '%s'" % (actual, expected))    

if __name__ == "__main__":
    check(parse("(a)"), " Apple ")  # simple template
    check(parse("(a)(b)"), " Apple  Banana ")  # two templates
    check(parse("(a(b(c)))"), " Apple  Banana  Car ")  # nested template
    check(parse("(a(b(c(f))))"), " Apple  Banana  Car (f)")  # one missing nested template
    check(parse("(a)(b(c(d(f(g)))(e)))"), " Apple  Banana  Car  Dog (f(g)) Elephant ")  # two missing nested template

我通过使用基于PEG的解析器(解析表达式语法)解决了这个问题,这使我有机会了解它更精确的行为与我在编译器课程中学习的上下文无关语法之间的区别

?@melpomene我对使用它犹豫不决,但我更关心的是解决这个问题的算法选择(ast),而不是代码的质量。如果我怀疑这个算法,我还应该使用codereview吗?我不知道你在问什么。“展开宏”是什么意思?你的预期产出是多少?据我所知,内圆括号对代码的输出没有影响,这使得它很难理解它应该做什么。@Blckknght添加了更多的用例和更新解释。希望这能为你提出的问题提供答案。我还是不太明白你输入的括号是什么意思。据我所知,你应该可以把它们全部删除,然后翻译其他字符。
(a(b(c))
(a)(b)(c)
(a(b)(c))
之间是否存在差异?您当前的代码似乎不符合要求。