原創(chuàng)|使用教程|編輯:鄭恭琳|2017-12-28 14:48:47.000|閱讀 908 次
概述:語(yǔ)法解析這個(gè)系列文章總共有9個(gè)部分,在第2部分中,我們將學(xué)習(xí)語(yǔ)法的解剖學(xué),詞法分析器結(jié)束,解析器開(kāi)始,等等。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
相關(guān)鏈接:
緊跟第1部分,我們?cè)谡務(wù)摰摹按笏{(lán)景”還未結(jié)束,所以讓我們繼續(xù)……
形式語(yǔ)法是一組規(guī)則,它在語(yǔ)法上描述一種語(yǔ)言。
這個(gè)定義有兩個(gè)重要的部分:一個(gè)語(yǔ)法描述一種語(yǔ)言,但是這個(gè)描述只涉及語(yǔ)言的語(yǔ)法而不涉及語(yǔ)義。這就是說(shuō),它定義了它的結(jié)構(gòu),但不是它的意義。必要時(shí),必須以其他方式檢查輸入意義的正確性。
例如,假設(shè)我們要為在第1部分中定義分析的段落中顯示的語(yǔ)言定義語(yǔ)法。
HELLO: "Hello" NAME: [a-zA-Z]+ greeting: HELLO NAME
該語(yǔ)法接受諸如“Hello Michael”和“Hello Programming”之類(lèi)的輸入。它們?cè)谡Z(yǔ)法上都是正確的,但是我們知道“Programming”不是一個(gè)名字。因此,它在語(yǔ)義上是錯(cuò)誤的。語(yǔ)法不指定語(yǔ)義規(guī)則,并且它們不被解析器驗(yàn)證。您需要以其他方式確保提供的名稱(chēng)的有效性;例如,將其與有效名稱(chēng)的數(shù)據(jù)庫(kù)進(jìn)行比較。
為了定義語(yǔ)法元素,我們來(lái)看一個(gè)最常用格式的例子來(lái)描述語(yǔ)法:Backus-Naur Form(BNF)。 這種格式有許多變種,包括Extended Backus-Naur Form。Extended類(lèi)型的優(yōu)點(diǎn)是包含一個(gè)簡(jiǎn)單的表示重復(fù)的方法。另一個(gè)值得注意的變體是Augmented Backus-Naur Form,主要用于描述雙向通信協(xié)議。
Backus-Naur語(yǔ)法中的典型規(guī)則如下所示:
< symbol > ::= __expression__
< symbol >是一個(gè)非終端符,這意味著它可以被右邊的一組元素__expression__取代。 元素__expression__可以包含其他非終端符號(hào)或終端符號(hào)。終端符號(hào)就是那些在語(yǔ)法中任何地方都不以< symbol >出現(xiàn)的符號(hào)。終端符號(hào)的典型例子是一串字符,如“你好”。
規(guī)則也可以稱(chēng)為生產(chǎn)規(guī)則。從技術(shù)上講,它定義了非終端者與右邊的非終端者和終端者之間的轉(zhuǎn)換。
解析中使用的語(yǔ)法主要有兩種:正規(guī)文法和上下文無(wú)關(guān)文法。通常對(duì)于一種語(yǔ)法對(duì)應(yīng)同一種語(yǔ)言:一種正則語(yǔ)法定義一種正則語(yǔ)言等等。然而,還有一種更近期的稱(chēng)為解析表達(dá)語(yǔ)法(Parsing Expression Grammar,PEG)的語(yǔ)法,它與上下文無(wú)關(guān)的語(yǔ)法同樣強(qiáng)大,因此定義了上下文無(wú)關(guān)的語(yǔ)言。兩者的區(qū)別在于規(guī)則的表示和解釋。
正如我們已經(jīng)提到的那樣,這兩種語(yǔ)言處于復(fù)雜的層次結(jié)構(gòu)中——正則語(yǔ)言比上下文無(wú)關(guān)的語(yǔ)言更簡(jiǎn)單。
區(qū)分這兩種語(yǔ)法的一個(gè)比較簡(jiǎn)單的方法是,一個(gè)正則語(yǔ)法的正則表達(dá)式——也就是規(guī)則的右邊——可能只是其中的一個(gè):
這是很難檢查的,因?yàn)橐粋€(gè)特定的工具可以允許在一個(gè)定義中使用更多的終端符號(hào)。然后,工具本身會(huì)自動(dòng)將這個(gè)表達(dá)式轉(zhuǎn)換成一系列等同的表達(dá)式,這些表達(dá)式都屬于上述三種情況之一。
所以,你可以寫(xiě)一個(gè)與正規(guī)語(yǔ)言不兼容的表達(dá)式,但是表達(dá)式會(huì)以適當(dāng)?shù)男问奖晦D(zhuǎn)換。換句話(huà)說(shuō),這個(gè)工具可以為語(yǔ)法寫(xiě)作提供語(yǔ)法糖(syntactic sugar)。
在稍后的一段中,我們將詳細(xì)討論不同類(lèi)型的語(yǔ)法及其格式。
詞法分析器轉(zhuǎn)換一系列tokens中的一系列字符。
詞法分析器(Lexers)也被稱(chēng)為掃描儀或標(biāo)記器。Lexers在解析中起到了一定的作用,因?yàn)樗鼈儗⒊跏驾斎朕D(zhuǎn)換為適當(dāng)?shù)慕馕銎鞲子诠芾淼男问剑?析器則是在后期工作。通常來(lái)說(shuō),詞法分析器比解析器更容易編寫(xiě),雖然在特殊情況下,兩者都非常復(fù)雜。例如,在C的情況下(參見(jiàn)維基百科的)。
詞法分析器的一個(gè)非常重要的工作任務(wù)是處理空白。然而大多數(shù)情況下,您希望詞法分析器放棄空白。這是因?yàn)椋缛舨蝗坏脑?huà),解析器將不得不檢查每個(gè)單個(gè)標(biāo)記之間是否存在空白,這很快就會(huì)變得很煩人。
但是在某些情況下,你不能這樣做,因?yàn)榭瞻着c語(yǔ)言相關(guān),就像Python用來(lái)識(shí)別代碼塊一樣。即使在這種時(shí)候,通常情況下,詞法分析器會(huì)處理將相關(guān)空白與不相關(guān)空白區(qū)分開(kāi)來(lái)的問(wèn)題——這意味著您希望詞法分析器了解哪些空白與解析相關(guān)。例如,在解析Python時(shí),您希望詞法分析器檢查空白是否在關(guān)鍵字if和下面的表達(dá)式(不相關(guān))之間定義了縮進(jìn)(相關(guān))或空格。
鑒于詞法分析器幾乎完全與解析器一起使用,因此兩者之間的分界線(xiàn)有時(shí)會(huì)模糊不清。這是因?yàn)榻馕霰仨毊a(chǎn)生對(duì)于程序的特定需求有用的結(jié)果。所以,解析某個(gè)東西的方法不僅僅是一個(gè)正確的方法,而且您只關(guān)心滿(mǎn)足您需求的一種方式。
例如,假設(shè)您正在創(chuàng)建一個(gè)程序,該程序必須解析服務(wù)器的日志以將其保存在數(shù)據(jù)庫(kù)中。為了這個(gè)目標(biāo),詞法分析器將識(shí)別一系列的數(shù)字和點(diǎn),并將它們轉(zhuǎn)換成IPv4 token。
IPv4: [0-9]+ "." [0-9]+ "." [0-9]+ "." [0-9]+
然后,解析器將分析tokens的順序,以確定它是否是消息、警告等。
如果您正在開(kāi)發(fā)必須使用IP地址來(lái)識(shí)別訪(fǎng)客國(guó)家的軟件,會(huì)發(fā)生什么呢?也許你會(huì)希望詞法分析器識(shí)別地址的八位位置以備后用,并使IPv4成為解析器元素。
DOT : "." OCTET : [0-9]+ ipv4 : OCTET DOT OCTET DOT OCTET DOT OCTET
這是由于不同的目標(biāo),如何以不同的方式解析相同的信息的一個(gè)例子。
請(qǐng)繼續(xù)關(guān)注第3部分,我們將在其中討論語(yǔ)法、語(yǔ)義和解析器。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn