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