转眼间已经到了大三下学期了,马上就要实习了,最后一个学期我会好好珍惜的。为了让这个学期过的有格调,我打算每一件事情都做得有逼格一点。
开学第三周我们学校就开始陆陆续续有实验课了,做一个词法分析器? 好嘞,劳资要用Sourceinsight把开源的GCC里面的词法分析代码全部移植出来,就问你牛不牛批!!! 脑海中已经浮现出了助教对我异样的眼光,哈哈,不多说了,盘它!!!!!!
首先,进入gcc的官网,找到它最旧的一个版本(好像88年就有gcc了),但是我在官网上只能找到98年的。整个文件也才几百KB,打开下载好的源码,看了下就那么十多个.c文件,应该难度不大,这回稳了(脸上逐渐露出那啥的微笑)。找到gcc.c中的main函数,因为这是整个程序的执行入口,看了眼代码,有很多的宏外加简单的英文注释,一路shift+鼠标左键结合注释来查找我要移植的词法分析器在哪里(因为.c源文件中没有类似lexer.c之类的文件),已经记不清这是我第几次进入查看函数定义了,仿佛是在递归一样,有意思极了,反正我的脸都黑了。我倔强的坚持了一整个上午,心中慢慢的没底了,我是那么轻易就会放弃的人吗? 当然不是! 接着我又换了一个接一个版本的编译器,重复上述操作m次,每一次都“循环迭代”查看代码n次,最终得出了一个微弱的解!!!
下面我来说说这个来之不易的解吧,看论坛上有大神说Tiny C比较简单,我尝试了一下,的确能够看出点端倪的,大概又花了半天的时间,看懂了他的词法分析器实现的大概思路,不过有点煞风景就是了。书上说好的编译器分为预处理阶段、词法分析、语法分析、语义分析、中间代码生成以及优化、目标代码生成以及优化、链接(重定位),在这个开源项目中怎么不是这样子的呢?tcc_preprocess函数根据英文翻译过来的意思都能够理解的出是预处理嘛,但是他里面包括了预处理器和词法分析器,直接将两个功能混合在一起,达到了高耦合的水平,这样让我怎么移植嘛(要知道从这种开源的工业级软件中分离两个耦合在一起的功能难度不亚于和经期的女人吵架,不信你可以试试,额。。。我说的是去吵架),不过tcc_compile、tcc_assemble、tcc_load_archive都还封装的比较好,尽管tcc_compile包含了多个功能,但是它里面调用的都是高内聚的函数。
但是为什么这种开源编译器的实现会跟教材上面有那么大的差别呢,究竟是教材过时了还是编译器的开发者们只是能力欠缺啊?其实我觉得都不是,原因在于我脑残了,非得标新立异,结果被碰的头破血流。理论和实际有区别这是人之常情嘛,况且更重要的是我们需要看到开源的工业级的编译器它的功能不仅仅是生成可执行文件,他的DEBUG功能照样很强大,甚至能够帮我们探测到潜在的内存泄漏等,可以查看运行时的程序变量,程序调用栈等等(当然这些也许已经不属于我们所学的编译器中应该有的功能了,而应该称之为IDE),因此他的设计者那样实现肯定是有他们所考虑到的深层次的原因的;另一方面,编译原理这门课程讲的主要是编译器如何生成可执行文件,而不太关注编译器的报错机制,调试机制更是只字未提,而单独实现这一功能的编译器估计没人敢用吧(只要是名程序员都肯定会要那啥了)。
总结一下,这种工业级的软件真的不是我们随随便便就能摆弄、驾驭的了的,尤其是开源的,广泛使用的软件,开发他们的人、或者组织、或者许多组织不为钱,只为秀一波操作,这得有多大的勇气和自信心啊。我们所能够做的就是时刻保持一颗敬畏的心,如果把它比作一头愤怒的公牛,那么你就不要没事找事,非得学着斗牛士去斗牛,小心输的裤衩都没有。当具有了一定的能力,足以驾驭它的时候,你会发现对代码丢失了几分趣味。。。
原文地址:https://www.cnblogs.com/xwmcc/p/10505993.html