从开源编译器中移植代码的正确姿势

转眼间已经到了大三下学期了,马上就要实习了,最后一个学期我会好好珍惜的。为了让这个学期过的有格调,我打算每一件事情都做得有逼格一点。

开学第三周我们学校就开始陆陆续续有实验课了,做一个词法分析器? 好嘞,劳资要用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

时间: 2024-11-11 00:58:22

从开源编译器中移植代码的正确姿势的相关文章

向UBOOT中移植代码总结

1.首先,将要移植的代码目录(如bootpicsnd)整个拷贝到UBOOT工程中,最好放到对应的board目录下. 2.在bootpicsnd目录里,新建一个Makefile,参考如下: # # (C) Copyright 2000-2007 # Wolfgang Denk, DENX Software Engineering, [email protected] # # See file CREDITS for list of people who contributed to this #

在vue项目中封装echarts的正确姿势

为什么需要封装echarts 每个开发者在制作图表时都需要从头到尾书写一遍完整的option配置,十分冗余 在同一个项目中,各类图表设计十分相似,甚至是相同,没必要一直做重复工作 可能有一些开发者忘记考虑echarts更新数据的特性,以及窗口缩放时的适应问题.这样导致数据更新了echarts视图却没有更新,窗口缩放引起echarts图形变形问题 我希望这个echarts组件能设计成什么样 业务数据和样式配置数据分离,我只需要传入业务数据就行了 它的大小要完全由使用者决定 不会因为缩放出现变形问题

Intellij IDEA中使用Protobuf的正确姿势

一..proto文件语法高亮显示 需要安装Protobuf Support插件 依次点击Intellij中的"File"-->"Settings"-->"Plugins"-->"Browse repositories",如下所示: 输入Protobuf,如下所示 安装完后,重启Intellij IDEA,查看.proto文件,会发现已经支持语法高亮显示. 二.将.proto文件转成Java类 一般的做法,是执

Git提交代码的正确姿势

按此步骤基本没问题,中间有conflict,需要手动解决. 1.git stash 2.git pull 3.git stash pop 4.git add --xxx 5.git commit -m "msg" 6.git pull -r 或 git pull -rebase 7.git push origin HEAD:refs/for/master 不rebase可能会导致在没有主动创建分支的情况下,出现各种分支和merge. 原文地址:https://www.cnblogs.c

Node.js中使用redis数据库的正确姿势

Redis是一个常用的Nosql数据库,一般用来代替Memcached做缓存服务,同时它也支持数据的持久化,有着比较广泛的应用场景.在Java中使用redis我们已经比较熟悉了,那么在node.js和koa.js框架中使用Redis的正确姿势是怎样的呢? Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: * Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载

在Linux(ubuntu server)上面安装NodeJS的正确姿势

上一篇文章,我介绍了 在Windows中安装NodeJS的正确姿势,这一篇,我们继续来看一下在Linux上面安装和配置NodeJS. 为了保持一致,这里也列举三个方法 第一个方法:通过官网下载安装 https://nodejs.org/en/download/ 这种方式的问题是我们需要自己去找网页,找到链接,然后下载 第二个方法:使用apt工具进行安装 默认情况下,在apt的源中只有比较老的版本(注意,需要先apt-get update) 例如,如果运行apt-get install nodej

vim编译器中多行注释方法(尤其对python代码注释)

------------------------------------------------------vim编译器中多行注释-------------------------------------------------------- 在vim命令下编写python程序时,有时候要进行多行注释,比较麻烦.因为python不像c语言那样可以用/*xxxx*/进行多行注释,只能每一行用#来注释,如果有几百行那得注释到什么时候.除了老老实实的一行一行注释外,这里再分享几种方法: 第一种:把要注

[转]C,C++开源项目中的100个Bugs

[转]C,C++开源项目中的100个Bugs http://tonybai.com/2013/04/10/100-bugs-in-c-cpp-opensource-projects/ 俄罗斯OOO Program Verification Systems公司用自己的静态源码分析产品PVS-Studio对一些知名的C/C++开源项目,诸如Apache Http Server.Chromium.Clang.CMake.MySQL等的源码进行了分析,找出了100个典型的Bugs. 个人觉得这份列表对C

C/C++ 开源库及示例代码

C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1.3 环形缓冲 2.1.4 多维数组 2.1.5 图 2.2 对容器的操作 2.3 字符串处理 2.3.1 字符集 2.3.2 字符串格式化 2.3.3 正则表达式 2.3.4 (其它) 2.4 内存相关 2.4.1 智能指针 2.4.2 内存池 2.5 时间 & 日期 2.6 编码 & 解码