《自己手動寫乙個編譯器 聯結器》一(3)

2021-09-30 14:29:42 字數 1780 閱讀 7156

這次記錄的是語法分析(光看定義玖足夠暈人的,所以我看了一遍然後決定一邊重新梳理一邊記錄)

語法分析法有兩種,一種是自頂向下法,一種是自底向上法,兩種方法中最常用的是自頂向下法(這個方法也是書中所使用的,所以這裡沒有自底向上法的具體介紹,不過這個方法會在明天的筆記中補全)

自頂向下法又分為兩種,就是不確定的~和確定的~這兩種,所謂的自頂向下法就是指從開始符號串出發,反覆使用生產式,尋找匹配與輸入的串的引導。

其中確定的就是指遇到了乙個非終結符的產生式有很多的匹配項,此時就會引起回溯,這個就是為了試探應該使用哪乙個匹配項但那時效率低。

確定的呢,就是有唯一確定的匹配項,但是這個對文法有一定的限制。

接下來是ll分析器,這個分析器其實就是從左到右掃瞄,然後使用最左推導。

ll分析器被稱為ll(k)分析器時就表示這個分析要取決於向右掃瞄k位才可以確定應該選擇哪乙個推導式(其實這個ll(k)分析器就是乙個確定的自頂向下的分析器)這裡來舉兩個例子:

《校長》::=《老師》

《老師》::=」學生」

這裡就是乙個ll(0)文法(貌似沒有什麼意義)

《桃園結義成員》::=」劉備」|」關羽」|」張飛」

這個就是乙個ll(1)文法

ll(2)文法呢

《班級成員》::=」張三」|」王二」|」王三」

由此可以看出,只有為掃瞄到第二位才可以確定「王三」和「王二」的確定的推導

一般情況下都用的是ll(1)類文法

現在是最頭疼的地方就是這類文法的判別,先看定義。

一共有三種集first,follow,select這三種集。

第一種first集 first(a) =

按照書上的說法就是:

如果有x是終結符那麼first(x) =

如果有x是非終結符並且產生了x->終結符,那麼first(x)=

如果有x是非終結符並且產生了x->空符號串,那麼first(x)=

如果有x是非終結符並且y1,y2….同樣也是非終結符,並且產生了x->y1,x->y2….並且有y1…存在長度可能為0的推導->空符號串那麼就有first(x)=,並且如果y中求解步驟也要重複上面的步驟,直到first(x)=這個型別為止(在當x有終結符時終結符排除)。

簡言之,就是用於表示終結符如:

s→ap

s→bq

a→a

a→ca

b→b

b→d

first(s1) = first(a) =

(第乙個s->ap,其中a是非終結符,此時就推出了等於那乙個含有非終結符的a(終結符用於結束))

first(s2) = first(b)=

first(a1) =

first(a2) =

first(b1) =

first(b2) =

第二種follow(a)=

這裡就是乙個跟隨的關係

按照書上的定義就是

開始時加入乙個#進去就是fllow(s)=

如果存在a->abb這個產生式(大寫為非終結符)則把first(b)的非空元素加入follow(b)中,如果b存在長度可能為0的推導則把follow(a)也加入follow(b)中

重複上面那乙個直到不在增加。

第三種select按照書上的說法就是

如果有產生式a->a

求first(a)

如果first(a)中不存在空符號串則讓select(a->a)=first(a)否則救球follow(a)並令select(a->a)=first(a)和follow(a)的並集

《自己手動寫乙個編譯器 聯結器》一(1)

這次主要是記錄一些關於字母表,和文法的形式定義 基礎部分 字母表 這個字母表其實囊括了我們的符號和符號串的概念,大可以認為這兩個就是字母表的子集吧 對於字母表的分析要從兩個方面來看 詞法分析方面 從詞法分析來看我們的字母表其實就是原始碼字元 那麼對應的有符號和符號串的概念,其實 這個時候的符號就是這...

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

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

自己手動寫乙個HashMap

目錄 public inte ce map public class hashmapimplements map 通過key 進行hash index下表陣列 當前陣列對應的物件entry 判斷當前這個物件為空 如果是空的,直接可以儲存資料,如果不為空,就是hash衝突,所以要用鍊錶,然後返回這個儲...