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