Re: [問題] 如何學寫COMPILER? [純拋磚引玉]

看板Programming作者時間18年前 (2007/04/23 19:32), 編輯推噓2(200)
留言2則, 2人參與, 最新討論串23/38 (看更多)
※ 引述《sniffer@kkcity.com.tw ( )》之銘言: > 至少 BNF 代表前文不會影響後文的語法, > 這跟 bot 用的 parser 比起來就簡單得多, 也比 perl 好弄 > 好寫不好寫是要把所有 parser 拿出來排, 不是只跟 C compiler 比 > perl 都能用 yacc 做得出來, 還沒有很多 bug, > yacc 有問題還是寫的人有問題? 我印象中 BNF 可以描述 context-sensitive 的 syntax, 受到較多限制的 BNF 才會變成 context-free 和 regular expression, 所以我才說 BNF 可以高興怎樣寫就怎樣寫, 但是 parser 不見得做得出來。 > C++ 也還是老舊的, template 不是新觀念, 而且 C++ 連 > obj dynamic linking 都沒搞定, 本質上跟 C 是一樣的 > C++ 本來還是個 C 的 code generator: cfront > yacc 算是 4GL, goal oriented, 還比 C++ 新得多 > 新應該是指 style, 而不是訂規格的日期 我講的 80 年代 programming 技術, 指的是 yacc 這個工具 (無論是設計或是產生出來的 code), 跟 C++ 是不是新東西倒沒什麼關聯性, 重點是 2007 年用 yacc 去生 parser 的 code 已經非常不合時宜了, 做 parser 有更方便更容易除錯的 language-level library 可以使用。 至於 CFront 這個東西的原理, 只不過是開發任何軟體都會出現的一個過渡期現象罷了, 至今仍有不少 C-like 的 parallel programming language, 是先以 generate C code 為主, 這並不代表什麼, 只是開發新語言的某種工程面手段罷了。 template 之所以會鬧出這麼多 bug, 主因還是在於我前面所說的軟體開發問題, yacc 不適合用來產生一個「語法還會加入各種新元素」的 parser, 如果你稍微瞭解過 template (以及它的進階特性) 被加入 C++ 的年代, 你就會知道它其實是在 GCC 已經有 C++ parser 的狀況下才被加入的, 這時 GCC 裡面已經有了一個 yacc 寫好的過渡期版本, 固然 maintainer 可以選擇整個 .y .l files 打掉重新寫一份新的, 但是多數人都會選擇在現有的 .y .l files 上面改, 遺憾的是 flex (lex) 和 bison (yacc) 只對前者有利, 於是 maintainer 在跟無數的 bug 奮戰之後選擇了手工重寫。 > C++ 有多少人能說自己 100% 瞭解了, 並記得: > template of template > public, friend, protected > C 最多就是 function pointer 長得比較怪 > 不能完全瞭解的東西才會被亂搞 現在已經是 2007 年了, 不是 2000 年, 絕大多數人無法瞭解 C++ 超過 90% 程度的時代早已過去, C++ 標準動盪不安的時代也早已終結, 我也遇過 K&R C 一路到 C99 之間的各個大地震, 一堆人在 C89 (相對於 C++98) 出現的那十年間還不是對 C 有相似的抱怨, 但最後還不是一樣因為安定下來而被廣泛接受了, 相較之下現在 C99 新的特性才緩慢的被眾人接納, 這個狀況跟 C++98 可說是一模一樣。 你問現在 100% 熟悉 C++98 的人有多少, 但是你卻沒有注意 100% 熟悉 C99 的人又有多少, 這根本只是時間的問題而已。 template template 也不是什麼奇怪的東西, 只是因為不想在 template argument 丟一個明確的 instance 進去 (如 set<int>), 所以就直接把 class template 的名字丟進去 (以上例來說就是丟 set), 這些東西都是因為有需求才會產生, 然後才是探討 template parameter 那邊要怎樣寫; 如果用不到, 那麼不會也沒差。 至於 public private protected friend 這類東西, 會不懂的大概也只剩下 10 年前還是學生的叔叔伯伯姑姑阿姨了, 現在的學生成天都在摸 Java 和 C# 這類東西, 已經是絕對不可能不會的特性。 「新語言機制」是因應「舊語言技巧」而產生的, 所以如果你用不到, 那麼不會本來就沒差, C 語言本身簡單, 但也因此有各種旁門左道的技巧得學, 甚至還沒有書可以學全, 更沒有一套標準 (充其量只不過是公約), 新一代的語言把這些技巧標準化、通用化、光明正大化、語言機制化, 並不代表學的人就是什麼都要學會才行, 所謂「亂搞」並不會因為語言機制比較少就比較難發生。 回到原本講「亂搞」的部分, 要在 C 語言亂搞也很簡單, C 語言規定「字串」是一個某處以 NULL 結尾的 char array, C 語言處理字串的 library function 都假設 input 是字串, 但是它接受的 type 是 pointer to char, 所以有人故意或不小心塞了個普通的 char array 進去也行, 結果你 call 個 strlen() 程式就當了, 你用 debugger 去看會發現當在 libc 裡面, 而且你不一定有辦法看到 strlen() 的實作碼, 那麼你是會先 check 餵進 strlen() 的 argument, 還是說你打算直接開 assembly level debugging 進去跟他拼了? 是正常的 C programmer 幾乎不太可能選擇後者, 同理是正常的 C++ programmer 就不會吃飽太閒跑去幫 STL 實作碼 debug, 同理正常的 OO programmer 也不會需要知道什麼上下層 type 是什麼; 自己不瞭解的東西本來就不應該亂搞 (Exceptioanl C++ 一書就有建議不懂就別用), 這是管理面和制度面的問題。 今天你不用 C++ 而用 C 去寫程式, 你一樣得用上不少 C 特有的 tricks 才能滿足現代軟體多變的需求, 如果對這些 tricks 一知半解就隨便拿來用, 一樣也是叫做亂搞, debug 起來也是會讓人叫苦連天, 越是簡單的語言越是存在多得讓人摸不著頭緒的 tricks, 每個人都有自己的一套小絕招跟一組大絕招, 萬一哪個人突然給你來個跳槽不幹了, 那對整個 project 來說就是一大危機, 語言機制豐富的情況下這些神奇絕招的出現率就會降低, 因為對該語言來說不太神奇的絕招其實就已經非常夠用了, 而這些不太神奇的絕招要不就是書上會教, 要不就是雇用個對該語言熟悉度超強的人來就能看懂, 這些都是簡單語言所享受不到的好處, 因為就算你雇用到 C 語言超強的人, 他還是得花上非常多的時間去「參透」那位落跑仁兄的「大絕招」。 所以終歸還是那句話, 工具的選擇真的是非常重要的。 -- Name: Tseng, Ling-hua E-mail Address: uranus@it.muds.net School: National Tsing Hua University Department: Computer Science Interesting: C++, Compiler, PL/PD, OS, VM, Large-scale software design Researching: Software pipelining for VLIW architectures Homepage: https://it.muds.net/~uranus -- ╔═══╗ ┼────────────────────────╮ 狂狷 Origin:[ 狂 狷 年 少 ] whshs.cs.nccu.edu.tw ╰─╮ 年少 ┼╮ < IP:140.119.164.252 > ╰─╮ ╚╦═╦╝ From:61-230-220-241.dynamic.hinet.net ─╨─╨─ KGBBS 遨翔"BBS"的狂狷不馴;屬於年少的輕狂色彩 [修改]tinlans:61-230-220-241.dynamic.hinet.net 07/04/23 19:01:06

04/23 19:45, , 1F
好文.
04/23 19:45, 1F

04/23 21:01, , 2F
推~ 看到最後讓我想到大師兄...
04/23 21:01, 2F
buganini:轉錄至看板 HSNU_1085 04/25 06:15
文章代碼(AID): #16B9ap00 (Programming)
討論串 (同標題文章)
文章代碼(AID): #16B9ap00 (Programming)