從零寫乙個編譯器(六) 語法分析之表驅動語法分析

2022-07-04 06:30:13 字數 2381 閱讀 1623

專案的完整**在 c2j-compiler

在完成語法分析表之前,還差最後乙個任務,那就是描述reduce資訊,來指導自動機是否該進行reduce操作

reduce資訊在productionsstatenode各自的節點裡完成,只要遍歷節點裡的產生式,如果符號「.」位於表示式的末尾,那麼該節點即可根據該表示式以及表示式對應的lookahead set得到reduce資訊

reduce資訊用乙個map來表示,key是可以進行reduce的符號,也就是lookahead sets中的符合,value則是進行reduce操作的產生式

public hashmapmakereduce() 

private void reduce(hashmapmap, arraylistproductions) }}

}

語法分析表的構建主要在statenodemanager類裡,可以先忽略loadtable和storagetabletofile的邏輯,這一部分主要是為了儲存這張表,能夠多次使用

主要邏輯從while開始,遍歷所有節點,先從跳轉資訊的map裡拿出跳轉關係和跳轉的目的節點,然後把這個跳轉關係(這個本質上對應的是一開始token列舉的標號)和目的節點的標號拷貝到另乙個map裡。接著拿到reduce資訊,找到之前對應在lookahead set裡的符號,把它們的value改寫成- (進行reduce操作的產生式編號),之所以寫成負數,就是為了區分shift操作。

所以hashmap>這個資料結構作為解析表表示:

第乙個integer表示當前節點的編號

第二個integer表示輸入字元

第三個integer表示,如果大於0則是做shift操作,小於0則根據推導式做reduce操作

public hashmap> getlrstatetable() 

iterator it;

if (istransitiontablecompressed) else

while (it.hasnext())

}hashmapreducemap = state.makereduce();

if (reducemap.size() > 0)

}lrstatetable.put(state.statenum, jump);

}storagetabletofile(lrstatetable);

return lrstatetable;

}

語法分析的主要過程在lrstatetableparser類裡,由parse方法啟動.

和第二篇講的一樣需要乙個輸入堆疊,節點堆疊,其它的東西現在暫時不需要用到。在初始化的時候先把開始節點壓入堆疊,當前輸入字元設為ext_def_list,然後拿到語法解析表

public lrstatetableparser(lexer lexer)
語法解析的步驟:

public void parse() 

if (action > 0)

parsestack.push(lexerinput);

if (token.isterminal(lexerinput)) else

} else

int reduceproduction = -action;

production product = productionmanager.getinstance().getproductionbyindex(reduceproduction);

consoledebugcolor.outlnpurple("reduce by product: ");

product.debugprint();

// takeactionforreduce(reduceproduction);

int rightsize = product.getright().size();

while (rightsize > 0)

lexerinput = product.getleft();

parsestack.push(lexerinput);

// valuestack.push(attributeforparentnode);}}

} private integer getaction(integer currentstate, integer currentinput)

到現在已經完成了語法分析的所有內容,接下來就是語義分析了,但是在這之前還有乙個需要說的是,我們當前構造的有限狀態自動機屬於lalr(1)語法,即使lalr(1)語法已經足夠強大,但是依舊有lalr(1)語法處理不了的語法,如果給出的推導式不符合,那麼這個有限狀態自動機依舊不能正確解析,但是之前給出的語法都是符合lalr(1)語法的

這一篇主要就是

簡單編譯器之語法分析

ok,書接上文,今次這篇部落格是準備說語法分析。其實詞法分析和語法分析可以說是一體的。詞法分析用於分析輸入的單詞,將其一一分門別類。語法分析分析已經分門別類好的單詞,看其組成的句子是否符合語言的文法。首先,先確定乙個簡單的文法 s if m s n m p p p id digit n int id...

手工打造編譯器之語法分析器1

語法分析 分析程式的短語結構 文法描述一種語言。文法是如下產生式 production 的集合 symbol symbol,symbol 出現在左部的符號是非終結符 nonterminate 出現在右部的排除掉非終結符就是終結符 terminate 計算first,follow,nullable集合...

用Scheme寫乙個Scheme編譯器(一)

在博主的大學生涯中,感覺最頭痛的一門課程就是編譯原理了,學習完這門課程之後,雖然知道了ll,lr演算法,和一系列與編譯原理相關的術語,可是對它的了解一直停留在做題上,雖然博主一直希望能夠通過自己寫乙個編譯器來加深對編譯原理的理解,可是用c語言寫編譯器真的是一場噩夢,每天大把的時間都花在了除錯bug上...