Lex與Yacc學習(九)之Yacc語法

2021-06-28 08:27:43 字數 2075 閱讀 4854

本文討論yacc語法的格式並描述可用的各種特徵和選項

yacc語法包括三部分:定義段、規則段和使用者子例程段

...定義段...

...規則段...

...使用者子例程段...

各部分由以兩個百分號開頭的行分開,儘管某乙個部分可以為空,但是前兩部分是必須的,第三部分和前面的百分號可以省略。

yacc 語法由符號組成,即語法的「詞」。符號是一串不以數字開頭的字母、數字、句點和下劃線。符號error專用於錯誤恢復,另外,yacc對任何符號都不會附加「先驗」的意義。

由詞法分析程式產生的符號叫做終結符號或者標記。定義在規則左側的叫做非終結符號或者非終結。標記也可能是字面上引用的字元,通常遵循約定:標記大寫,非終結符號小寫。

定義段包括文字塊,逐字拷貝到生成的c檔案開頭部分的c**,通常包括宣告和#include行。可能有%union  %start   %token   %type   %left  %right  和 %nonassoc宣告。

也可以包含普通的c語言風格的注釋,所有這些都是可選的,在簡單的語法分析程式中,定義段可能完全是空的。

規則段由語法規則和包括c**的動作組成。

yacc 將使用者子例程段的內容完全拷貝到c檔案中,通常這部分包括從動作呼叫的例程。

動作是yacc與在語法中規則相符時執行的c**,動作一定是c復合語句。

通過使用後面跟有數字的美元符號,動作可以查閱在規則中與符號有關的值,冒號後面跟的第乙個符號是數字1,例如:

date:month  '/'  day   '/'  year

而名字,$$是指冒號左邊符號的值,符號值可以有不同的c型別。

由於語法有歧義或者包含衝突,yacc對於語法規範的翻譯可能會失敗。一些情況下,語法確實有歧義,也就是說對於乙個單獨的輸入字串有兩種可能的分析而且yacc處理不了。

另外一些情況,語法並無歧義,但yacc使用的語法分析技術不足以分析這個語法。

當乙個輸入字串有兩種可能的分析時,而且其中乙個分析完成乙個規則(歸約選項),而另乙個卻沒有(移進選項)時,移進/歸約衝突便發生了。

例如:

%%

e: 『x』

| e '+' e

;

對於輸入字串「x+x+x」 ,有兩種可能的分析: 「(x+x)+x」或者「x+(x+x)」,採用歸約選項使得語法分析程式使用第乙個分析,而採用移進選項則使用另乙個。

當同樣的標記可以完成兩個不同的規則時,就會發生歸約/歸約衝突。

例如:

%%

prog: proga | progb

proga: 'x' ;

progb: 'y' ;

乙個「x」可能是proga,也可能是progb。

大多數歸約/歸約衝突沒這麼明顯,但是幾乎在任何情況下它們在語法中都表現為錯誤。

由於yacc處理符號標記而不是文字,它的輸入字符集比起lex來說就簡單的多,下面列出了yacc所使用的特殊符號的列表:

具有兩個%標記的行將yacc語法分成了幾部分;

定義段的所有宣告都是以%開始,包括%    %union  %start   %token   %type   %left  %right  和 %nonassoc宣告。

反斜線符號是廢棄的百分號同義詞,在動作中,c語言字串中有其通常作用。

在動作中,美元符號引入乙個值引用,舉例來說,$3表示規則右端第3個符號的值。

文字標記由乙個單引號結束,例如 'z' 。

在乙個動作的值引用中,可以不考慮尖括號包圍起來的預設型別。

有些yacc版本在文字標記中將單引號和雙引號同等對待,這樣使用根本不方便。

動作中c**在大括號中。

除了後面緊接著是以豎線開頭的規則外,規則部分每個都是以分號結束。

當連續兩個規則具有相同的左端,第二個規則可用乙個 | 代替符號和冒號。

在每一條規則裡,左端的每個符號後面都跟著乙個冒號。

符號可以包括和字母、數字以及句點在一起的下劃線。

符號可以包括與字母、數字、下劃線一起的句點。

早期版本使用,現已不推薦。

Lex與Yacc學習(十)之Yacc庫

每個實現都需要有用的例程庫,在unix系統中,可以通過cc命令列尾端給出 ly標誌 或通過其他系統下的等價物 來包含庫。庫的內容在不同的實現之間是不同的,但總是包括main 和yyerror yacc的所有版本都帶有最小的主程式,該程式對於簡短程式和測試有時是很有用的,它非常簡單,如下所示 main...

Lex與Yacc學習(四)之Lex規範

lex程式由三部分組成 定義段 規則段和使用者子例程式段 定義段.規則段.使用者子例程式段.這些部分由以兩個百分號組成的行分隔開。儘管某一部分可以為空,但前兩部分是必須的,第三部分和前面的 行可以忽略。定義段包括文字塊 定義 內部表宣告 起始條件和轉換。以空白開頭的行被逐字拷貝到c檔案中,通常,這用...

Lex與Yacc的結合

lex與yacc的結合 首先,我就不介紹lex的語法規則了,因為在一些書上這些是重點介紹的內容,我先把lex的源程式寫在下面,然後講解。number 0 9 其中 define number 257 define plus 258 define sub 259 define chen 260 def...