2016-11-05 70 views
1

我正在使用PLY解析包含嵌套塊的文件。 典型:Python 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,以便我可以在我的示例中檢索到dc的孩子,該孩子本身就是a的孩子,因爲我必須知道解析器中的父規則。

我應該在p_nodesp_node中輸入什麼信息才能建立有效的AST?謝謝。

回答

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) 
+0

不幸的是,分析器幹不允許像'p [0] = Node(p [3],p [0])'這樣的東西。此外,如果信息在創建期間尚未收集,我不會在創建AST後看到如何做到這一點。 什麼也讓我卡住是規則'節點:節點節點|節點「意味着在這個層次上產生的所有節點規則必須是AST中的兄弟節點,並且如果沒有」範圍「概念,似乎很難做到這一點,因爲在解析器級別存在遞歸,並且在AST級別上這些節點必須處於相同的深度。 – ibi0tux

+0

我已經更新了我的答案,應該做你想做的。告訴我你是否還有一些問題。 –

+0

好吧,這個作品完美,你保存了我的週末,非常感謝你! 'p [0] = [p [1]] + p [2]'符號正是我所錯過的。 – ibi0tux