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