看板Programming
标 题Re: [问题] 如何学写COMPILER? [纯抛砖引玉]
发信站政大狂狷年少 (Mon Apr 23 19:01:06 2007)
转信站ptt!ctu-reader!ctu-peer!news.nctu!netnews.csie.nctu!news.cs.nthu!WHSHS
※ 引述《[email protected] ( )》之铭言:
> 至少 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:
[email protected]
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
1F:推 horngsh:好文. 59.126.181.10 04/23 19:45
2F:推 tf1515:推~ 看到最後让我想到大师兄...140.116.103.201 04/23 21:01
※ buganini:转录至看板 HSNU_1085 04/25 06:15