Bison介绍[转]
轉(zhuǎn)載自:https://zhuanlan.zhihu.com/p/89479111
Bison是一種通用解析器生成器,它將帶注釋的上下文無(wú)關(guān)文法轉(zhuǎn)換為使用LALR(1)解析器表的確定性LR或廣義LR(GLR)解析器 。作為一項(xiàng)實(shí)驗(yàn)性功能,Bison還可以生成IELR(1)或規(guī)范的LR(1)解析器表。一旦您精通Bison,就可以使用它來(lái)開(kāi)發(fā)各種語(yǔ)言解析器,從用于簡(jiǎn)單臺(tái)式計(jì)算器的語(yǔ)言解析器到復(fù)雜的編程語(yǔ)言。 Bison與Yacc向上兼容:所有正確編寫(xiě)的Yacc語(yǔ)法都應(yīng)與Bison一起使用,而無(wú)需進(jìn)行任何更改。熟悉Yacc的任何人都應(yīng)該可以輕松使用Bison。您需要精通C或C ++編程才能使用Bison。還支持將Java作為實(shí)驗(yàn)功能。
Bison由三部分組成
- 定義部分
- %%
- 規(guī)則部分
- %%
- 用戶附加的C語(yǔ)言部分
定義部分
代碼部分
%{ ... %},或%code { ... }的內(nèi)容都是C代碼,并將代碼照搬到生成的C文件中,可以定義一些函數(shù)聲明,結(jié)構(gòu)體,類型等,還可以重定義一些Bison的宏,從而改變程序的規(guī)則。
聲明%name
與flex %option類似,提供一定機(jī)制來(lái)控制bison默認(rèn)規(guī)則。
8. %type<>,Bison構(gòu)造%type用于聲明非終結(jié)符。 以前我們以前沒(méi)有使用%type,因?yàn)榉墙K結(jié)符通常由定義它們的規(guī)則隱式聲明。 但是必須顯式聲明exp,以便我們可以指定其值類型。
9. %token<>,token類型定義。在PostgreSQL中為關(guān)鍵字定義。
10. 優(yōu)先級(jí)定義,為了避免過(guò)多的語(yǔ)法沖突,在這里定義一些語(yǔ)法優(yōu)先級(jí),從上到下優(yōu)先級(jí)依次遞增
%nonassoc SET /* see relation_expr_opt_alias */ %left UNION EXCEPT %left INTERSECT %left OR %left AND %right NOT %nonassoc IS ISNULL NOTNULL /* IS sets precedence for IS NULL, etc */ %nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS %nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA %nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */ %left POSTFIXOP /* dummy for postfix Op rules */規(guī)則部分
規(guī)則分為規(guī)則/行為行和C代碼行。
規(guī)則/行為
bison語(yǔ)法是由一系列的規(guī)則組成。每個(gè)規(guī)則由非終結(jié)符開(kāi)始,然后是“:”和可能為空的符號(hào)、文字記號(hào)和動(dòng)作的列表。 例如:
simple_select:SELECT opt_all_clause opt_target_listinto_clause from_clause where_clausegroup_clause having_clause window_clause{SelectStmt *n = makeNode(SelectStmt);n->targetList = $3;n->intoClause = $4;n->fromClause = $5;n->whereClause = $6;n->groupClause = $7;n->havingClause = $8;n->windowClause = $9;$$ = (Node *)n;}|………………;代碼段
此段落,postgresql, 定義了一些在規(guī)則段中使用的工具函數(shù)。
移進(jìn)/歸約
移進(jìn):bison語(yǔ)法分析器通過(guò)查找能夠匹配當(dāng)前token的規(guī)則來(lái)運(yùn)作。當(dāng)bison處理一個(gè)語(yǔ)法分析器時(shí),他創(chuàng)建一組狀態(tài),每個(gè)狀態(tài)都反應(yīng)出一個(gè)或者多個(gè)部分分析過(guò)的規(guī)則中可能的位置。當(dāng)語(yǔ)法分析器讀取記號(hào)時(shí),每當(dāng)它讀到的記號(hào)無(wú)法結(jié)束一條規(guī)則時(shí),它將把這個(gè)記號(hào)壓入一個(gè)內(nèi)部堆棧,然后切換到一個(gè)新?tīng)顟B(tài),這個(gè)狀態(tài)能夠反映出剛剛讀取的記號(hào)。這種行為被稱為移進(jìn)。
歸約:當(dāng)它發(fā)現(xiàn)壓入的所有語(yǔ)法符號(hào)已經(jīng)可一以組成規(guī)則的右部時(shí),他將把右部符號(hào)全部從堆棧中彈出,然后把左部語(yǔ)法符號(hào)壓入堆棧。這種行為被稱為歸約。因?yàn)樗ǔO麥p了堆棧中一定數(shù)量的符號(hào)。每當(dāng)bison歸約一條規(guī)則時(shí),它會(huì)執(zhí)行該規(guī)則關(guān)聯(lián)的用戶代碼。
二義性
只要是對(duì)于語(yǔ)言的解析,往往都會(huì)伴隨二義性的問(wèn)題。bison把語(yǔ)法翻譯為成語(yǔ)法分析器時(shí)有可能會(huì)報(bào)告沖突。一些情況下,語(yǔ)法確實(shí)有歧義;也就是說(shuō)。對(duì)于一個(gè)輸入的字符串,存在兩種可能的語(yǔ)法分析器,而bison無(wú)法處理這種情況。(當(dāng)然也有可能是bison對(duì)于某些規(guī)則不支持的緣故)。 bison的二義性沖突分為移進(jìn)/歸約沖突和歸約/歸約沖突。 移進(jìn)/歸約沖突:
%% e: 'X'| e '+' e;在這里,當(dāng)我們輸入X+X+X時(shí),存在兩種可能,(X+X)+X和X+(X+X)。移進(jìn)會(huì)按照第二條規(guī)則進(jìn)行,而歸約會(huì)按照第一條規(guī)則進(jìn)行,這時(shí)就會(huì)存在矛盾。 移進(jìn)/歸約沖突:
%% prog: proga | progb ;proga: 'X'; progb 'X';移進(jìn)不會(huì)產(chǎn)生歧義,但當(dāng)歸約時(shí),X既是proga又是progb,這就會(huì)造成歸約/歸約沖突。
工作流程
圖片來(lái)自于同事,bret.shao
flex&bison協(xié)作方式
官方文檔
https://www.gnu.org/software/bison/
總結(jié)
以上是生活随笔為你收集整理的Bison介绍[转]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: RIP是个什么样的协议?
- 下一篇: easyui后台界面如何添加选项卡(Ta