Re: [問題] 如何學寫COMPILER? [純拋磚引玉]
※ 引述《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
討論串 (同標題文章)
完整討論串 (本文為第 23 之 38 篇):
Programming 近期熱門文章
PTT數位生活區 即時熱門文章