Python PLY 解析:定义范围

Python PLY parsing : definition scope

我正在使用 PLY 来解析包含嵌套块的文件。 通常:

a {
    b {

    }
    c {
        d {

        }
    }    
}

我正在使用像这样的简单语法:

def p_nodes(p):
    '''
    nodes : node nodes
          | node
    '''
    # ??

def p_node(p):
    '''
    node : IDENTIFIER OPEN_CURLY_BRACE node_çontent CLOSE_CURLY_BRACE
    '''
    p[0] = Node(p[3])#FIXME?

def p_node_content(p):
    '''
    node_content : nodes
                 |
    '''
    if len(p) > 1:
        p[0] = p[1]
    else
        p[0] = None

我想知道我可以访问解析器中的 'parent' 节点。换句话说,我如何构建 AST 以便我可以在我的示例中检索 dc 的子级,它本身是 a 的子级,因为我必须对父规则可见在解析器中。

我应该在 p_nodesp_node 中输入什么才能构建有效的 AST?谢谢。

我们需要您的 Node class,但我认为它类似于:

class Node:
    def __init__(self, children):
        self.children = children
        self.type = None

那么你的解析器可能看起来像这样:

def p_nodes(p):
    '''
    nodes : node nodes
          | node
    '''
    if len(p) > 2:
        p[0] = [p[1]] + p[2]
    else
        p[0] = [p[1]] 

def p_node(p):
    '''
    node : IDENTIFIER OPEN_CURLY_BRACE node_content CLOSE_CURLY_BRACE
    '''
    p[0] = Node(p[3])

def p_node_content(p):
    '''
    node_content : nodes
                 |
    '''
    if len(p) > 1:
        p[0] = p[1]
    else
        p[0] = None

那么你将拥有一个真正的 AST,每个节点都包含对其所有子节点的引用。

最后,如果你想让你的节点引用它们的父节点,你必须从根开始迭代所有的 AST,并将它设置为他所有子节点的属性,然后对它的子节点做同样的事情。 ..

为此,请将您的 Node class 更改为如下所示:

class Node:
    def __init__(self, children):
        self.children = children
        self.parent = None

    def set_parent(self, parent):
        self.parent = parent

和运行类似的函数:

def set_parent_to_AST(root_node):
    for node in root_node.children:
        node.set_parent(root_node)
        set_parent_to_AST(node)