原創|使用教程|編輯:鄭恭琳|2017-12-29 17:01:17.000|閱讀 711 次
概述:語法是用來描述語言的一套規則,因此研究規則的格式是很自然的。這就是我們在這個9部分系列的第4部分中所要做的。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
語法是用來描述語言的一套規則,因此研究規則的格式是很自然的。然而,典型語法中還有幾個元素可以引起進一步的關注。其中一些原因是因為語法也可以用來定義其他職責或者執行一些代碼。
首先,我們將討論在解析中可能遇到的一些特殊規則或問題。
如果你閱讀語法,你可能會遇到許多其中只定義了幾個tokens的東西,而不是全部。就像這個語法一樣:
NAME : [a-zA-Z]+ greeting : "Hello" NAME
token “你好”沒有定義,但既然你知道一個解析器處理tokens,你可能會問自己這怎么可能。答案是有些工具會為您生成字符串文字的對應token,以節省您一些時間。
請注意,這可能只在某些條件下才有可能。例如,使用ANTLR,如果您定義了單獨的詞法分析器和分析器語法,則必須自己定義所有的tokens。
在解析器的上下文中,一個重要的特性是支持左遞歸規則。這意味著一條規則從對自身的引用開始。有時候,這個參考也可能是間接的;也就是說,它可能出現在第一個引用的另一個規則中。
考慮例如算術運算。一個加法可以被描述為由加號(+)分隔的兩個表達式,但是加法的操作數可以是其他的加法。
addition : expression '+' expression multiplication : expression '*' expression // an expression could be an addition or a multiplication or a number expression : multiplication | addition | [0-9]+
在這個例子中,表達式通過規則的加法和乘法包含對自身的間接引用。
此描述也匹配多個添加如5 + 4 + 3。這是因為它可以解釋為表達式(5)('+')表達式(4 + 3)(規則加法:第一個表達式對應于選項[0 -9] +,第二個是另外一個)。然后4 + 3本身可以分為兩個部分:表達式(4)('+')表達式(3)(規則加法:第一個和第二個表達式都對應于選項[0-9] +)。
該問題是左遞歸規則可能不能用于一些解析器生成器。另一種選擇是長鏈表達,也關心運營商的優先級。不支持這些規則的解析器的典型語法看起來與此類似:
expression : addition addition : multiplication ('+' multiplication)* multiplication : atom ('*' atom)* atom : [0-9]+
正如你所看到的,表達式是按照優先順序的相反順序來定義的。因此,解析器會將低優先級的表達式放在最低級別的表達式中;因此,他們將首先執行。
一些解析器生成器支持直接的左遞歸規則,但不支持間接的。請注意,通常,問題是不支持左遞歸規則的解析算法。因此,解析器生成器可以將以正確的方式寫成左遞歸的規則轉換成使其與其算法一起工作。在這個意義上,左遞歸支持可能是(非常有用的)語法糖。
規則轉換的具體方式因語法分析器的不同而不同, 然而,邏輯保持不變。表達式分為兩組:一組有運算符和兩個操作數和原子。在我們的例子中,唯一的原子表達式是一個數字([0-9] +),但也可以是括號((5 + 4))之間的表達式。這是因為在數學中,括號被用來增加表達的優先級。
一旦擁有了這兩個組,就可以維護第二組成員的順序,并顛倒第一組成員的順序。原因是人類以先到先得的原則推理:按優先順序編寫表達式比較容易。
然而,解析的最終形式是一棵樹,它運行在一個不同的原理上:你開始在樹葉上工作,并在這個過程結束時,根節點包含最終結果——這意味著在解析樹的原子表達式在底部,而帶有運算符的那些則以相反的順序出現。
謂語(有時稱為句法或語義謂詞)是特殊的規則,只有在滿足某個條件的情況下才能匹配。該條件是用編寫語法的工具所支持的編程語言中的代碼定義的。
它們的優點是它們允許某種形式的上下文相關的解析,這有時是不可避免的匹配某些元素。例如,它們可以用來確定定義一個軟關鍵字的字符序列是否被用在關鍵字的位置(即前一個關鍵字后面可以跟著一個關鍵字),還是一個簡單的標識符。
缺點是它們減慢了解析速度,并且使語法依賴于所述編程語言。那是因為條件是用編程語言表達的,必須檢查。
嵌入式操作辨認每次匹配規則時執行的代碼。由于規則被代碼所包圍,它們有明顯的缺點,使得語法難以閱讀。此外,就像謂語一樣,它們打破了描述語言的語法和操縱解析結果的代碼之間的分離。
不太復雜的解析生成器經常使用操作作為在節點匹配時輕松執行某些代碼的唯一方法。使用這些解析器世代,唯一的選擇是遍歷樹并自己執行正確的代碼。更高級的工具反而允許使用訪問者模式()在需要的時候執行任意代碼,并且管理樹的遍歷。
它們也可以用來添加特定的tokens或更改生成的樹。雖然不美觀,但這可能是處理像C這樣的復雜語言或像Python中的空白這樣的特定問題的唯一實用方法。
請繼續關注第5部分,我們將主要討論語法格式。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn