原創|使用教程|編輯:鄭恭琳|2017-12-28 14:14:59.000|閱讀 2604 次
概述:語法解析這個系列文章總共有9個部分,在第1部分中,我們將學習正則表達式的語法,解析器的結構以及什么是無掃描解析器。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
當我們列出用于Java、C#、Python和JavaScript解析的主要工具和庫時,我們已經介紹了一些解析術語(需要這些方面文章資源的同學可以聯系Elyn獲取哦)。在本文中,我們將更深入地介紹解析中使用的概念和算法,以便您更好地理解這個迷人的世界。
在這篇文章中我們試圖做到實用。我們的目標是幫助從業者,而不是解釋完整的理論。我們只解釋你需要知道的知識來理解和構建解析器。
語法解析被定義為“根據語法規則組織數據的輸入分析”。
有幾種方法來定義解析。然而,要點仍然是一樣的:解析意味著找到我們給出的數據的底層結構。
從某種意義上說,解析可以被認為是模板的逆過程:識別結構并提取數據。在模板中,我們有一個結構,并填充數據。在解析的情況下,您必須從原始表達中確定模型,而對于模板,則必須將數據與模型結合以創建原始表達。原始表達通常是文本,但也可以是二進制數據。
從根本上講,解析是必要的,因為不同的實體需要不同形式的數據。解析允許以特定軟件可以理解的方式來轉換數據。一個明顯的例子就是程序——它們是由人類編寫的,但是它們必須由計算機來執行。所以,人們用一種他們能理解的形式寫出來,然后一個軟件以一種可以被計算機使用的方式來轉換它們。
但是,即使在兩個具有不同需求的軟件之間傳遞數據時,解析也是必要的。例如,當你需要序列化或反序列化一個類時,就需要它。
在本節中,我們將描述解析器的基本組件。我們不是要給你正式的解釋,而是實際的解釋。
正則表達式是可以由模式定義的一系列字符。
正則表達式經常被吹捧為你不應該用來解析的東西。這是不正確的,因為你可以使用正則表達式來解析簡單的輸入。問題是一些程序員只知道正則表達式,所以他們用它們來解析所有的東西——甚至是他們不應該解析的東西。其結果通常是一系列非常脆弱的正則表達式一起被入侵。
您可以使用正則表達式來解析一些更簡單的語言,但是這排除了大多數編程語言——甚至是那些看起來很簡單的編程語言,比如HTML。事實上,可以用正則表達式解析的語言稱為常規語言。它有一個正式的數學定義,但超出了本文的范圍。
該理論的一個重要結果是常規語言也可以被有限狀態機()解析或表達。也就是說,正則表達式和有限狀態機同樣強大。這就是他們被用來實現詞法分析器的原因,我們將在后面看到。
常規語言可以由一系列正則表達式來定義,而更復雜的語言則需要更多的東西。一個簡單的經驗法則是,如果語言的語法具有遞歸或嵌套的元素,那么它就不是一種常規的語言。例如,HTML可以在任何標簽內包含任意數量的標簽;因此,它不是一個普通的語言,不管它是多么的巧妙,都不能用正則表達式來解析。
典型程序員對正則表達式的熟悉使他們經常被用來定義語言的語法。更確切地說,它們的語法被用來定義詞法分析器或分析器的規則。例如,在一個規則中使用Kleene星號(* )來表示一個特定元素可以呈現為零或無限次數。
該規則的定義不應與實際的詞法分析器或分析器如何實現相混淆。您可以使用您的語言提供的正則表達式引擎來實現詞法分析器。但是通常,語法中定義的正則表達式被實際轉換為有限狀態機來獲得更好的性能。
澄清了正則表達式的作用之后,我們可以看一下解析器的一般結構。完整的解析器通常由兩部分組成:詞法分析器,也稱為掃描器或標記器,以及正確的解析器。解析器需要詞法分析器,因為它不直接在文本上工作,而是在詞法分析器產生的輸出上。并不是所有的解析器都采用這個兩步模式。一些解析器不依賴于單獨的詞法分析器,而是將兩個步驟結合起來。 他們被稱為無掃描程序分析器。
詞法分析器和解析器按順序工作:詞法分析器掃描輸入并生成匹配的tokens;解析器然后掃描tokens并產生解析結果。
讓我們看看下面的例子,想象我們正試圖解析加法。
437 + 734
詞法分析器掃描文本并找到4、3和7,然后找到一個空格( )。 詞法分析器的工作是識別字符437構成NUM類型的一個token。然后詞法分析器找到一個+符號,它對應于PLUS類型的第二個token,最后找到另一個類型為NUM的token。
解析器通常會組合詞法分析器生成的token并對它們進行分組。
詞法分析器和解析器使用的定義稱為規則或產品。在我們的例子中,詞法分析器規則將指定一個數字序列對應于NUM類型的token,而解析器規則將指定類型NUM、PLUS、NUM的token序列對應于一個求和sum表達式。
現在通常找到可以生成詞法分析器和解析器的套件。過去,結合兩種不同的工具比較常見:一種是生成詞法分析器,另一種是生成解析器。例如,這是一個古老的lex和yacc共同使用的情況:使用lex,可以生成一個詞法分析器,而使用yacc時,可以生成一個解析器。
無掃描器解析器的操作方式不同,因為它們直接處理原始文本,而不處理由詞法分析器生成的tokens列表。也就是說,一個無掃描解析器就像一個詞法分析器和一個解析器結合在一起。
雖然知道調試的目的,如果一個特定的分析工具是一個無掃描程序的分析器是非常重要的,但在很多情況下,定義一個語法是沒有意義的。這是因為你通常還是定義了組合字符序列的模式來創建(虛擬)tokens;然后,你將它們結合起來,以獲得最終結果。只是因為這樣做更方便。換句話說,無掃描程序的語法分析器的語法看起來與具有單獨步驟的工具非常相似。再次,你不應該為了方便而混淆事物是如何定義的,以及它是如何在幕后工作的。
請繼續關注第2部分——我們將詳細討論解析器和語法。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn