<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    10.7. 全部放在一起

    你已經了解很多基礎的東西。讓我們回來看看所有片段是如何整合到一起的。

    作為開始,這里是一個接收命令行參數的腳本,它使用 getopt 模塊。

    
    def main(argv):                         
    ...
        try:                                
            opts, args = getopt.getopt(argv, "hg:d", ["help", "grammar="])
        except getopt.GetoptError:          
    ...
        for opt, arg in opts:               
    ...

    創建 KantGenerator 類的一個實例,然后將語法文件和源文件傳給它,可能在命令行沒有指定。

        k = KantGenerator(grammar, source)

    KantGenerator 實例自動加載語法,它是一個 XML 文件。你使用自定義的 openAnything 函數打開這個文件 (可能保存在一個本地文件中或者一個遠程服務器上),然后使用內置的 minidom 解析函數XML 解析為一棵 Python 對象樹

        def _load(self, source):
            sock = toolbox.openAnything(source)
            xmldoc = minidom.parse(sock).documentElement
            sock.close()

    哦,根據這種方式,你將使用到 XML 文檔結構的知識建立一個引用的小緩沖,這些引用都只是 XML 文檔中的元素。

        def loadGrammar(self, grammar):                         
            for ref in self.grammar.getElementsByTagName("ref"):
                self.refs[ref.attributes["id"].value] = ref     

    如果你在命令行中指定了某些源材料,你可以使用它;否則你將打開語法文件查找“頂層”引用 (沒有被其它的東西引用) 并把它作為開始點。

        def getDefaultSource(self):
            xrefs = {}
            for xref in self.grammar.getElementsByTagName("xref"):
                xrefs[xref.attributes["id"].value] = 1
            xrefs = xrefs.keys()
            standaloneXrefs = [e for e in self.refs.keys() if e not in xrefs]
            return '<xref id="%s"/>' % random.choice(standaloneXrefs)

    現在你打開了了源材料。它是一個 XML,你每次解析一個節點。為了讓代碼分離并具備更高的可維護性,你可以使用針對每個節點類型的獨立處理方法

        def parse_Element(self, node): 
            handlerMethod = getattr(self, "do_%s" % node.tagName)
            handlerMethod(node)

    你在語法里面跳來跳去,解析每一個 p 元素的所有孩子

        def do_p(self, node):
    ...
            if doit:
                for child in node.childNodes: self.parse(child)

    用任意一個孩子替換 choice 元素,

        def do_choice(self, node):
            self.parse(self.randomChildElement(node))

    并用對應 ref 元素的任意孩子替換 xref,前面你已經進行了緩沖。

        def do_xref(self, node):
            id = node.attributes["id"].value
            self.parse(self.randomChildElement(self.refs[id]))

    就這樣一直解析,最后得到普通文本。

        def parse_Text(self, node):    
            text = node.data
    ...
                self.pieces.append(text)

    把結果打印出來。

    
    def main(argv):                         
    ...
        k = KantGenerator(grammar, source)
        print k.output()
    97av