【问题标题】:How do you construct a parse tree during LL(1) parsing?在 LL(1) 解析期间如何构造解析树?
【发布时间】:2020-05-01 19:47:49
【问题描述】:

我想知道是否有办法在 LL(1) 解析期间构造解析树。我已经尝试了几天,但一直找不到解决方案。 This 的问题类似,但没有提供足够的实现细节,而且是针对 AST,而不是解析树。

详情:

  • 我正在使用堆栈

【问题讨论】:

  • 解析树是 AST 的一种情况(其中没有任何东西被抽象掉:-))并且链接答案中提出的两种解决方案实际上都会产生解析树。你试过其中一种吗? (我认为您不能说带有实际工作代码的答案“没有提供足够的实现细节”。它可能不是用您想要的语言编写的,但在这种情况下,您需要指定哪些语言是可接受的: -) 并提供足够的工作代码来避免不可避免的“我们不为你编写代码”的尖刻 cmets。
  • (当然,那些刻薄的 cmets 是不正确的。很多人在这里提供了一个金盘子上的代码,尽管他们可能不应该这样做,因为它只会鼓励提出不好的问题。但这通常不会除非代码真的很容易编写。)
  • @rici -- 是的,我确实尝试了第一个。问题是它没有足够的实现细节,比如何时退出当前的 AST。
  • 当前 AST 节点完成后离开。骨架是产生式的右侧,每次遇到 AST 节点时都填写一个符号。所以你知道什么时候结束。
  • this answer 有推荐算法;它从答案的中间开始。

标签: compiler-construction stack abstract-syntax-tree ll parse-tree


【解决方案1】:

我会这样做:

示例语法:

statement -> number
statement -> '(' statement '+' statement ')'
number-> 'n'

结果:

RULES = [
    ["number"],
    ['(', "statement", '+', "statement", ')'],
    ['n'],
]

执行 ll 解析: "((n+n)+n)" -> ll -> [1,1,0,2,0,2,0,2] 您将获得已执行规则的列表

现在你可以建一棵树了

def tree(input, ll_output):
    rule = ll_output.pop(0)
    tokens = []
    for item in RULES[rule]:
        if len(item) > 1: tokens.append(tree(input, ll_output))
        else: tokens.append(input.pop(0))
    return tokens

input = ['(','(','n','+','n',')','+','n',')'] # "((n+n)+n)"
ll_output = [1,1,0,2,0,2,0,2]
tree(input, ll_output)
# -> ['(', ['(', [['n']], '+', [['n']], ')'], '+', [['n']], ')']

【讨论】:

    猜你喜欢
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 2021-01-03
    • 2023-04-11
    • 2012-08-23
    • 1970-01-01
    相关资源
    最近更新 更多