我正在使用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
我想知道我能够访问解析器中的“父”节点。换句话说,如何构建AST以便我可以在我的示例中检索d
是c
的孩子,a
本身就是p_nodes
的孩子,因为我必须能看到父规则在解析器中。
我应该在p_node
和{{1}}中放置什么才能构建有效的AST?感谢。
答案 0 :(得分:2)
我们需要你的Node
课程,但我认为它类似于:
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 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)