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


Yacc語法

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

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

                                          { printf ("date %d-%d-%d  found",$1,$3,$5);}

而名字,$$是指冒號左邊符號的值,符號值可以有不同的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代碼在大括號中。

;

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

|

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

:

在每一條規則里,左端的每個符號后面都跟着一個冒號。

_

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

.

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

=

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







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM