果然還是SB了

2022-03-24 12:46:42 字數 3658 閱讀 7260

編譯原理的龍書和虎書,各看了兩章之後,¥……&……*……@%¥

好吧,既然是碼農,就要從基層做起,我嘗試handwritten一下c或者c的極小子集的one-pass編譯器先,等有了深切的體會再去研究那些高深的形式理論也不遲。於是,我花了幾天搞了簡單的詞法分析,還費了一包子力,憑我那捉急的智商,湊出來乙個像是語法樹的東西,能解析四則運算表示式。書上說手寫編譯器用遞迴下降法最合適,我想了半天也不知道咋遞迴下降。。剛才看了看書上的簡化手寫語法分析器,一共才100行不到,我只好望書興嘆了,唉,底子完全不夠硬啊,差得遠啊。

寫了幾天hardcode的一點心得:

終於有點明白為什麼書上要我們把文法的bnf產生式都列出來,然後再相應的為每個產生式寫實現函式了,這其實是在演算法解耦。 比如我們可以測試發現,下面的遞迴下降語法器是不支援unary operator的,比如3*-2。如果想加入這個運算規則,我們只需在文法中新加入一條規則,然後修繕文法,最後編碼:在遞迴下降的層次中加入乙個unary()函式,下層是factor(),上層是term(),完成。如此便可以通過加新的函式來擴充套件支援邏輯運算,比較運算。而如果像我那樣hardcode的話。。。。。。。擴充套件的時候翔的感覺一下子就出來了。

而且考慮到類似這樣的語法特性:

a = b = c = 1;

利用遞迴下降法也能完美簡潔的解決啊!

為什麼要編譯原理?因為我手寫的玩意已經越來越義大利麵條了,每擴充乙個feature真是牽一髮而動全身,自己都完全不能確定有沒有給其他地方引入bug,也許最後能編譯一般的c**檔案了,但是我tm都不知道為什麼它能運作,當要移植到其它平台或者想複用來做個其它語言的編譯器時,只能傻眼了.這正是所謂的"靠人品程式設計".此乃碼農的標誌性特徵:先把功能趕完,bug可不敢說沒有有的話大不了加班修修補補唄...大神們做最基礎的編譯器時可不敢懷著這種大無畏精神...雖然我的義大利麵條杯具了,但是不錯的是認識到了編譯原理的重要性..

貼上**:

標準的遞迴下降語法器:

1 #include 2 #include 3

4char token; /*

全域性標誌變數*/5

6/*遞迴呼叫的函式原型*/7

int exp( void);8

int term( void);9

int factor( void

);10

11void error( void ) /*

報告出錯資訊的函式

*/12

1617

void match( char expectedtoken ) /*

對當前的標誌進行匹配

*/18

22void message(void)23

30main()

3145

46int exp( void)47

58return

temp;59}

6061

int term( void)62

77 temp /=div;

78break;79

}80return

temp;81}

8283

int factor( void)84

92else

if ( isdigit( token )) /*

實際的數字

*/93

98else error(); /*

不是括號也不是數字

*/99

return

temp;

100 }

我那翔一般的**:

1 #include "

stdafx.h

"2 #include "

syntaxtree.h

"3 #include "

compiler.h"4

5 etokentype syntaxtree::lasttokentype =etokentype_invalid;67

intsyntaxtreeopnode::evaluate()813

else

if (!strcmp(op, "-"

))14

17else

if (!strcmp(op, "*"

))18

21else

if (!strcmp(op, "/"

))22

25else

2631}32

33bool syntaxtreeopnode::isthisoppriorityhigher( const

char*s )

3437

38int

syntaxtreeleafnode::evaluate()

3942

43int

syntaxtreerootnode::evaluate()

4448

49syntaxtree::syntaxtree()

50:root(nullptr)

5153

54 syntaxtree::~syntaxtree()

5558

59bool syntaxtree::constructtree(int

len)

6088

else

if (curnode->isthisoppriorityhigher(op))89

97else

98102 curnode =node;

103vecflatnodes.push_back(node);

104}

105else

if (type ==etokentype_constantnumber)

106109

else

if (type ==etokentype_lbracket)

110121 --substr_len;

122}

123if

(bfind)

124

136else

137141 type =etokentype_constantnumber;

142}

143else

144148 lasttokentype =type;

149}

150151

//2.然後為每個運算子插入葉節點

152if (root->rchild ==nullptr)

153157

158 size_t leaf = 0, totalleaf =vecnums.size();

159for (size_t i=0; ii)

160172

else

173177

}178

if (!node->rchild)

179188

else

189193

}194

}195

196return

true

;197

}198

199void

syntaxtree::resettree()

200204

205int

syntaxtree::evaluate()

206

最後,無意中看到了這哥們擺弄的玩意,貌似也比我好不到哪去。。。。。。哇哈哈哈,可悲的咱碼農啊

果然,還是這樣安心些

今天,看會昨天買的書姐就回來了.做飯吃飯,洗洗襪子.發現才七點多.坐著看起大四時候的書了.因為考研,當時沒怎麼學.書中先說的hibernate 因為是別的框架的持久層.是啊這裡不會有任何東西是能難住我的.像這樣東西就在那.要的就是去理解分析.我對這種形式.額我一這樣就自信心爆棚.就像回到學生年代一樣...

生活果然還是美好的呀

是的。有這麼多高樓!這麼多帥哥!這麼多pp衣服!這麼多遊戲!天堂呀 v 自己找到的工作上上心裡舒服多了。儘管會貧窮一陣子 但是目前我最需要的是快樂 也許這就是面試那天我稀里糊塗就決定立刻上班的最好理由了。今天簽了各種合同,想著自己已經不那麼自由了 但是如果時刻抱著享受生活的態度,那麼還有什麼可怕的 ...

還是想你了

又想你了,怎麼辦?人有的時候真的很賤,是不是?也有不少人說過很欣賞我,關於我的種種優點,但那些都是可有可無的,我最期待的還是你的一句認可。我知道自己在你的眼裡什麼都不是,充其量是 好朋友 誰知道呢。可我偏偏就是認定你了,呵呵,受孽傾向,對,就是這樣。其實真的很想給你打 但害怕打擾你,影響你學習。回想...