
我的征尘是星辰大海。。。
-------当记忆的篇章变得零碎,当追忆的图片变得模糊,我们只能求助于数字存储的永恒的回忆,
作者:黄教授
一月四日 天有阴晴,月有圆缺
昨天,看了《我的野蛮女友》心情很郁闷。今天总算完成了让我太阳穴疼痛多日的scanner。不过,对于注释的输出处理得不好,所以,当注释很长的时候,会有些问题。但是原来的作业要求并不是那样。先这样吧,否则今天的心情就更加郁闷了,难道是因为参加老朱家的party?我想这不是真正的原因。但是,心却莫名的疼痛。。。改了好几次,总算完成了。我自己都觉得有些不可思议,我为什么要去实现"nested comment",实现并没有什么,问题是有什么意义呢?难道你要求程序员写注释的时候都要考虑括号匹配?我纯粹有些无聊。为了绕过feof,我不得不用ifstream,而这时我一向不喜欢的,为了能够把空格,回车换行符都读到,我不得不用一个低级函数get,结果换行符成了1310,我只能把这两个都当作是whitespace。这真是烦。我还突发奇想把程序的源码当作输入文件,知道这是自动机的那个鬼证明题在作怪吧?你不明白?当然了,不是computer science的有几个明白?当然了,那个源代码被改得七零八落的。
一月七日 雪霁
我还不敢开始我的parser,因为和scanner比起来难度是几何级数,这正如context-free-language的复杂度不是regular language所能比拟的。很多基本的算法我都还不懂。去找教授没找到,却看到一幅有趣的漫画,其中的寓意与孔圣人所谓的人需要鞭策异曲同工,我应该就是这么一个贱骨头,如果价格合适的话,我也许应该去买这样的东西。回来的路上,在地铁里倾听“地铁音乐家”的即兴创作,其中那位爱沉思创作的电子琴手的演奏让人流连忘返,仿佛引领你的想象力在无边无际的原野驰骋。我的parser也许应该是OO并非简单的object-oriented而是operator-oriented,因为所有的语言里都是operator为中心的。
玩了一会儿c++的宏命令,因为,我一看到Java就总觉得恶心,这种小孩子的玩意儿,我猜想肯定如同当初我学Delphi一样都是人家做出几个类包装好了你设定几个属性,对着回调函数写事件函数,那时候好有成就感啊!结果学了半天并不是在学习什么编程,只不过是学习其他程序员的编程习惯,包括变量函数的命名习惯,因为,你天天在用的就是别人命名的方法名字。想到这里我就来气,想起不知道在那里看到的一段议论,大意是业界使用开发工具来把程序员变成白痴,大学则是想方设法与之抗衡,但是随着越来越多的大学使用Java这种白痴工具,看来这种竞争中工业界占了上风。一气之下,我决定定义一行宏以后统统用sesame open door来代替using namespace std。
一月十日 酷冷
半夜醒来,想写一个“语法”阅读器,因为CFG本身也应该以文件的形式来读入,可是,问题没有想清楚,结果就如同“软件工程”这门课里介绍的一样,一个project半途而废。我不知道在我开始写parser之前还要准备多久。
一月十二日 冷酷
磨蹭了好几天才完成了一个如此简单的小程序:context-free-grammar reader。是否有人明白其中的用途?因为要写一个parser,而他会不断地需要检查语法,此外,假如我们可以由用户定义语法,势必要有这么一个语法阅读器,不用说去除left-recursion就更是需要了。写在还很不完备,仅仅是从文件读入了,对于一个数组来说添加删除是一件很头痛的事情,就把语法修改的任务放到下一步吧?因为我想吃饭了。
无聊之际跑到sinoquebec发现我一年前贴的帖子现在还在,不过把年份换成了2004。
一月十四日 零下31度,加上风力你会认为是零下43度(是摄氏不是华氏)
我不明白究竟零下30度和零下四十度有多大的区别,我也不明白在这样的清晨里在户外做苦力会给你留下多深的印象,我只知道当我坐在我的小屋里迎面看着从门窗射进来的刺眼的阳光时候,头脑中也如这惨白的阳光一样一片空白,人的记忆难道真的如沙滩上的脚印一样朝朝暮暮地被海浪洗刷的一干二净?我记得我的scanner所用的我自以为很独特的方法不过是table-driven的一种变形,而且不容否认的是table-driven比函数数组来的更有效率,更容易扩展,因为,在编译器的设计里,函数都是一种奢侈品。我记得我的梦想随着我的前进一步步地模糊,我记得我曾经以为自己是一条一天到晚不停地游泳的鱼,我记得我总是沉浸在深度搜索里几十层以下畅游的乐趣,我记得我总是幻想创造一种新的语言,我记得我时时刻刻意识到自己是一个凡夫俗子的痛苦。我记得什么?我只记得我今天冒着严寒干了一早上挣了20块钱。除此之外,没有什么了。
以后要记住‘0d*’代表八进制,‘0xd*’代表十六进制。要在c里面表示单引号:‘\'’。双引号同理,'\'单独用在macro里做换行符,feof有函数和macro两个版本,我也不知道编译器用哪一个,干脆以后直接用FILE里面的flag来判断好了。
一月十五日 阳光灿烂可是应该很冷很冷的
与jeppeter君商榷,你的mailbox退信,故改在这里了。
Is template a kind of macro in C++?
一月十六日 下雪了吗?
The several stupid mistakes I made when first using java.
一月十八日 天下着大雪
殚精竭虑,夙兴夜寐,终于完成了table-driven-scanner。我为了效率考虑,不惜去初始化一个138x72的巨大的表,同时还有别的表,用尽了我所能想得出的dirty trick。一般情况下我是不大喜欢把code写的这么tricky且无延展性的,可是效率,效率,效率。以至于我甚至把15个关键字也纳入了DFA的状态了,就不用说256个ASCII字符了。
一月二十三日 天晴了
scanner有一些小毛病,比如错误出现的行号会差一行,因为,换行符被读到的时候正好是token结束的时候,同时error-handling的机制要改进以便将来整个compiler都可以来调用。其他都是小问题,就不值一提了。在旧书摊买了一本关于二次大战中加密解密的故事,我觉得学计算机科学的学生都应该来读一读,因为信息科学乃至所有的科学文化都无非是一个加密解密的过程。在amazone订购的英文版<besieged fortress>过了半年才到。
下午想转到另一个section没有成功,心情很郁闷,我并不是100%认为Dr.Probst是一个不学无术的教授,可是,至少他的方法我认为是失败的:在学生还没有接触任何实际的一个操作系统的解决方案之前向学生灌输独立于操作系统的原则与思想是非常危险的,也是非常无用的。我不可能荒废一个学期时间来学习理解加拿大电视台里快嘴主持人的俏皮话。痛苦之余只好写一个奇怪的字典聊以自慰。这是一个奇怪的数据结构,也许受Huffman编码的启发吧,我一直觉得我没有能在数据结构的学习中尝试自己写Huffman编码是一个很大的遗憾,为什么在Concordia不讲讲这个有意思的东西呢?在效率与节省内存之间我总是捉摸不定,一开始我曾经想用一个快速字典来查询,也就是每一个字母下有26个字母,这样一个巨型的树需要多少字节呢?即便我用最精省的bool来表示,一个所有单词不超过8个字母的字典需要大约200G的内存,太夸张了!所以,我只能缩减为链表结构。当很多词有类似的拼写的时候,或者说有很多相同的子串的时候,我的结构比二叉搜索树有更好的效率,并极大地节省了内存。当然,我的字典非常难以删除一个词。
一月二十九日 晚上开始下小雪了
346的作业实在是bullshit!这不是我说的,这是“阿里”说的,不过也是我所想说的。
354的project需要一个简单的文字显示界面,我想把这种routine的layout的工作简单化,就写了一个Layout manager。原理很简单,说起来好笑就是把每一个可显示的对象定义为长方形,那么这个对象会有一个左上角和右下角的坐标,这个区域内的显示让对象自己去通过一个pure virtual的方法displayRow来实现,其他部分的default的显示就交给Layout Manager来做了。
一月三十一日 这是补记的日记,忘记天气了
二月一日 天气好象是不错的,忘了
If you cannot see Daemon, I can show you. Anyway I shouldn't say about the minor issues.
Maybe we should neglect the minor one and concentrate on the Deamon.
二月二日 天阴沉沉的
Either my English is too poor or we are not talking about same question. I think I have to ask someone else.
What a wonderful explanation!!! And finally we caught the subtle daemon! Mokhov 可以说是我在Concordia里不多几个值得敬佩的研究生了。
这几天我被动态链接库所折磨,被多线程编程所折磨,理不出头绪,各位客官是否有那位能够在dll得编译上指点我一下?先谢过了。
二月三日 阳光明媚
二月五日 下了一天一夜的大雪
写这个语法阅读器真是累。熬了半个通宵才完成了一个功能:common-left-factor这是语法修正的两个内容之一,我的预想是这个功能完成之后,再remove-left-recursion的时候就不用担心有两个以上的left-recursion了。但是,同一个variable有三个或三个以上的语法有common-left-factor怎么解决?CLF不止一个token呢?这些都解决了,不过好累啊。
二月六日 又开始下雪了
殚精竭虑,夙兴夜寐,昨晚是连骗带哄的完成了语法阅读器中的remove-left-recursion的第一个小功能,也算是一个版本吧?
早晨不甘心我在dll编译上的挫折,又重新来过,终于不负苦心,明白了必须加extern "C"的编译指示,而且也可以从delphi里调用了,从此,可以重新考虑图形界面的选择了。昨天有人告诉我说昨天是元宵节,昨天又看到北京看灯会踩死很多人,中国真是一个遥不可及的世界了。
二月八日 天晴了,阳光灿烂了
我总是无法完成我的计划。今天早上起来把上一次的烂尾工程做完了---remove-left-recursion的第二个部分,remove-immediate-recursion,意外的收获是发现我原来的想法不对,我本来认为在RLR与CLF之间应该先做CLF这样就可以取掉一个以上的immediate-left-recursion。结果我发现这样做会产生redundant variable,所以我就先做RLR再作CLF至少这样不会有redundant variable了,看起来舒服多了,再说怎样去出redundant variable绝对不是我现在所能完成的,I am pretty sure about it!虽然First set刚开了个头,我想还是先保存这个版本吧?另外,我把前一个 版本里面难懂得代码改了改,尽可能写成小函数,比较好读一些。
二月九日 晴天一个霹雳!
我的天!当我看到{...}这样的meta symbol对我的语法阅读器不亚于一个晴天一个霹雳!天哪!我怎么去表示这种语法呢:A -> L { , L }这里的{...}相当于Kaleen star这怎么来表示呢?还有对于我已经完成的RLC,CLF以及First set来说,这也是一个大大的问题!而且更严重的问题并不是在计算Follow set,因为那只是表示方法的问题,在parser的过程之后的sematical analyser 才是大大的问题!我简直不敢想下去了。不过还好老师给的语法好像不会有大问题,至少现在是这样。我现在已经没有太多的选择了,只好走一步,看一步了。不过令人欣慰的事,我的工作并非完全是无意义的,也就是说我花了一个星期写的工具并非一个傻瓜可以不用这个工具随随便便在十五分钟内用手工完成。(不过脑子灵便的应该可以吧?可是,我想单单用手key in这样繁琐的工作很难不出错吧?我相信电脑不相信人脑。有那位有不同意见不妨看看这样的语法。这里是电脑优化过的去除了left-recursion, common-left-factor的结果。)为保险起见,现存一个first的版本再去计算follow。
二月十日 天没有塌下来
其实都是庸人自扰!{}与|有什么本质的区别呢?我昨天就是脑子转不过弯来。今天拼了老命才把follow写完,虽然难度上和first一样,甚至代码都很相似,问题是其他相应的bug层出不穷,我先是为了{}的错误在付出代价,把它取出就是一个麻烦事情,后来又发现,即便是RLC与CLF依然会产生redundant variable。我没有办法了!虽然能够去除明显的redundant,但是多余的语法我实在不想再去除了。太累了,当这个类超过一千行代码时,我对他的作用开始产生怀疑了,而且,我单单磨刀就用掉了一个多星期,parser的影子还没有看到呢。我不敢再去优化他了。暂且这样,还不知道以后会发现多少bug呢?
二月十二日 天气很好
昨天心情一直不好。昨天夜里更遇到噩梦般的问题,几乎使得我一个星期的工作夭折。我的scanner是手写出来的,我没有去动态地产生token-type,这样即便我的parser是根据语法产生的,我怎么能够把scanner返回的token-type和我的语法里的token对应起来呢?另外,我的NT-Table建立的时候会检查语法是否符合LL(1),我还发现了我的程序没有办法替换非直接的common-left-factor。我只好硬生生地把那个捣蛋的语法放到出错的语法前面强迫先进行left-recursion的替换。此外,我发现我还有很多繁琐的工作忘记作了,比如去除一个token的代价是改变整个表,绝对不会比去除一条语法来得少。所以,干脆不去掉了。先暂时保存一个版本吧?
二月十三--十四日 今天天气好象还不错:小雪(我说的是昨天也就是十三日)
终于完成了我的parser:一个我可以少许为之骄傲的工程,一个自动读入以E-BNF形式写成的CFG语法;一个自动进行去除left-recursion,common-left-factor的语法优化器;一个自动计算所有non-terminal的First, Follow set的语法计算器;一个自动生成LL(1)语法的parsing table;一个以parser为核心的,由parser驱动的table-driven的scanner;一个table-driven的parser;一个相对独立的错误处理小模块;一个我呕心沥血费时近一个月(parser+scanner)写成,将近三千行代码的,也许marker只用十分钟就胡乱批改完的工程。(我真想痛骂他几句,并不是所有的学生都会像我这样傻傻地费这么大的力气来学编译器吧?即便是研究生也不一定会有几个会去写这种吃力不讨好的东西,对吧?那么我是否应该得到最起码的尊重?)而且,我一直有一个观点,这个也是从去年教我C++的那个老师那里得到的:没有写过超过两千行代码的单个程序的程序员是不会有面向对象的需求的。(当然,不要告诉我你写的是图形界面的程序,因为,那种程序别人替你做得太多了,你自己写的如果有两三千行的话整个程序应该非常的大了。
如果,我把它作为情人节的礼物,不知道有没有女孩子想要呢?哈哈。。。应该不会吧?
随便玩玩frontpage做做实验。
二月十四日 好像要下雪了
和黄勇探讨离散数学获益不少,又把以前的问题再讨论了一遍。实际上对于特殊形式的Chinese Remainder Theorem的问题:
S = M (mod p) (1)
S = M (mod q) (2)
(1) +(2) + gcd(p,q)=1 ==> S = M (mod p*q) 并不需要用到chinese remainder theorem按照黄勇的简单的obvious地证明法:(1)+(2) ==> (S-M)|p and (S-M)|q 。根据P183的Lemma1(S-M) | p*q因为:(1) ==> exists some k such that (S-M) = k*p; (2) ==> k*p | q ; and gcd(p,q)=1 + Lemma1 ==> k | q ==> (S-M) | p*q。
想知道Lemma1是什么? a*b |p + gcd(a,p)=1 ==> b | p
二月十五日 天又变冷了
早上把作业小小改动了一下,因为我实在是没有耐心去做那种机械重复的工作,只好用程序来做。下午睡了一下午,晚上和朱春明同学夜话数据结构与离散数学,回来意犹未尽就想玩玩多线程,结果成了四不像。我本意是dining-philosopher的问题,写的时候想到的是bounded-buffer,后来改成了reader-writer,实际上什么也不是,我不想仅仅把pseudo-code翻译成c++。那么改来改去就不知道在干什么了。
二月十七日 天气倒是很好
我们伟大的教授总是习惯于用他那种奢侈的方式来浪费宝贵的内存,目的仅仅为了方便他那不习惯于c形式的index。这样的程序用什么意义呢?对于parallel prefix sum来说,除非有多个cpu否则会有更好的效率吗?当然这是一个小孩子的玩意给初学多线程编程的学生做的。
二月十八日 寒流依然肆虐着大地。。。
透过双层玻璃窗注视着我的阳光是那么的炙烈,现在的白天依然短过黑夜,冬天会踯躅到五月,夏天短暂而热烈,那时候庆祝的人流里有美酒和音乐,而现在这里还是冰雪的世界,在24小时开着暖气的日子里,我的星辰大海般的征尘就是我的一切。。。
想去公共图书馆看书,结果没有开门,正好去区政府领取“回收箱”,一切手续都那么简单自然,不禁让人想到马恩列斯描述的“当社会财富极大丰富的时候,社会所要做的就是按需分配”,这不就是在某种程度上是国人的理想吗?可是,我耳闻目睹的却多的是抱怨,更多的是向往国内某种人压迫人,人剥削人的制度。一辈子抬轿子过苦日子的奴隶翻身解放之后,不是先尽情享受自由的幸福,而是首先想尝一尝当初所痛恨的坐轿子的生活。最想当奴隶主的其实是那些整天被压迫的奴隶,正如同所有的农民起义领袖最终都要做皇帝一样,而几乎所有的产业工人也都向往着做一个资本家。人剥削人,人压迫人的不是制度,可能只是人类的本性。
地铁的音乐家是我所敬仰的一群,从学校图书馆回来,又看到那个胖键盘手在即兴创作,我可以体会他沉浸在音符里的快乐,也许正如同我对BIT&BITE操作的乐趣。我以前除了汇编几乎没有去玩过BIT的操作,今天为了节省内存空间,不得不把SHIFT&REDUCE的信息放在一个代表STATE的整数的高位,因为,我的LR(0)语法表不想用结构来存储。碰到一个白发苍苍的老人家向我要零钱,我就把我仅有的几毛钱硬币给了他,心情觉得很愉快。我想只有穷人才会真正帮助穷人吧。monk地铁站的那个吉他手弹得很敬业,他的吉他都破的绑上胶布了,可是,他还是一如既往的弹着那时而激越,时而幽咽的古典吉他曲。
二月十九日 天气好热
按照老师的code练习了一下dining philosopher这样经典的线程同步的问题。我发现我只有具体写的时候才真正理解了每个philosopher需要三个状态的用意,才明白是每一个吃晚饭的philosopher的责任来唤醒他两旁的人来吃饭。但同步以外的一个显示的问题还是解决不了,就是每一个线程用cout来显示的时候会一团糟,我试图给显示部分统统加一个mutex,但是这个会影响到整个线程的运行。最后,我只好将结果全部存到一个数组里,等线程结束的时候才显示。这实在是一个笨办法,不知道各位看官有什么高招,我将不胜感激。
二月二十一日 昨天开始下雪了
这是昨天完成的sleeping barber的小程序,应该是一种简单的练习吧?
二月二十三日 晴
今天和朱春明同学区看大教堂,有一次感受到了中西方文化的冲击,我们再一次对中国文化里的繁文缛节不切实用的倾向作了最深刻的批判。吃完饭看到艺术广场上的“暖亭子”,就是大功率的红外加热管做的小亭子,人们可以在最冷的冬天里坐在露天喝咖啡,晒太阳,真好。简单的写了几个基类,是用在console里显示用的。
二月二十四日 大晴天
console里的类又改了很多,加了几个中间类。黄教授和小韦买了鱼和酒,我也喝了一杯,,基本上晚上就是放假了。不过红酒这东西总是让人心里有些怅惘与迷茫。听着王菲的歌曲,格外的有滋味:天晓得,既然说,你快乐就是我快乐。。。
二月二十五日 又是晴天
二月二十六日 天光光
加了一个rummy来验证同花,顺子,和group(就是炸弹了),并且加了一个接受用户输入的简单的类--CListener,并把以前写好的字典稍稍的改动了一下。
二月二十七日 又是一个大晴天
354的project暂时有了一个初步的样子,我想再回到我的被打断的LRParser来,这时候才体会到他的复杂性,我仿佛是一个奉命突击的战士,当我已到达冲锋的位置的时候我才发现我还不理解命令的实质,又好像一个初次登临讲坛的讲师自以为一切了然于胸而到了现场被一个简单的提问就蒙住了。正如Professor Grogono的email里说的,当你准备讲稿的时候才发现你其实并不了解你要讲的问题。我想编程序的最大的好处就是,除非你对这个问题十分的清楚一直到每一个细节,否则,you are stuck for sure,不管你看书的时候多么的自以为懂了,都没有用。我想今天似乎锐气已经挫尽了,暂时重新整顿一下再说吧。
胡乱逛来逛去,找到我以前在csdn.net上贴得AVLTree的源代码,有个家伙的评价是AVL比较难实现的是remove而我却没有实现,当时很不服气,我也记不清我以前是怎么做的,就回了个帖子说AVL从BST(Binery Search Tree)继承来的,remove的方法可以照样用的原因,使我把AVL内部remove的实现改过了,后来仔细看代码才发现,我好像当时并没有实现,因为,insert就已经很复杂了,我奋战了好几天,后来没有做remove,很惭愧,只好下午补课。真是好复杂,而且好像没有现成的算法,也就是说,造成不平衡的要移动的节点并不一定在被remove掉的节点的一侧,这样问题就复杂了。而且,应该转动的balance factor为+/-2的节点的两个子节点有可能factor都等于0.这样是和insert大不一样,我没有办法,只好看到一个情况改一个,天知道是否还会有别的情况,海,有谁知道算法?
二月二十八日 加拿大的天是晴朗的天
早上看了一个上午的Mr. bean就是不想做我的作业,我现在仿佛对programming以外的作业都提不起兴趣来了。朱春明同学提出一个很有意思的问题,使得我去查c++的源代码,看到了其中一个从未见过的操作符重载operator void*()。
二月二十九日 阴天
三月二日 现在还是临辰,不知道什么天气
LR(0)也许是我第一次让我对自己的程序失去信心的一个吧?我写到后来简直不敢相信程序有可能运行。因为,创建一个DFA需要的东西太多了!我对这个东西前后思考了一个多星期,真可以使夙兴夜寐,殚精竭虑了。当我运行出来一对结果时候我已经不再奢望去进行检验了。能run就好了。
三月四日 我昨天刚刚把冬天的衣服收起来,现在好像又要下雪了
LR(0)完成了初步的修正,改掉了一些bug,主要是类似于left-recursion导致死循环创建DFA的状态,还有就是parsing table的mask里面int类型问题,这个困扰了我许久:一个32位的掩码在和我的状态值“与”操作后居然不能再与这个32位的掩码比较了,也许微软编译器把0优化为一个较短的数了,我是这么猜测的。当然也发现了我一个stupid bug。我居然用16进制的0xd01111111来做掩码,这是好笑。我不想做一个临时的LR(0),所以,想直接就建立LR(1)或者SLR(1)等等。不过,parser还没有写出来,虽然不会复杂,还是要多想想,因为,还有很多问题不明白,再次验证了,只有写程序来实现才真正明白要解决的问题。现保存一个版本吧。当一个类的实现部分超过两千行代码的时候,维护工作确实变的有些棘手。
三月五日 天下着小雨,中雨
去实验室完成了project的一两个新功能。
三月六日 晚上居然开始下雪了
朱春明同学请客去了一家中国人的karaoke,门票5块钱,进去后看到的一群男女觉得好像又回到了福建乡下老家安海镇。保存一个版本吗?算了,明天再说吧,有点不好意思称之为版本了。
三月七日 阳光灿烂,哪里看得出来又下过雪?地上干干净净的
The professor is an idiot on programming。。。
I don't bother to guess his word puzzle as long as my program works.
Is algorithms in PA2 more efficient than that in PA1?
改正了java多线程程序中的算法,现在是按照老师的意图了,对于多cpu来说应该有更高的效率,可是,我得到的解释却是五花八门的。
写了一个模板实现的hash-table。希望能够写的尽量通用,可是,用template传入用户自定义的方法这一点上我很为难,太多了使用不便,太少了又缺乏通用性,是否模板与继承总是一对矛盾的双方呢?
我觉得我没有办法再去攻克comp354的project里的DFA,这对我来说是一件痛苦的事。我以前总认为DFS是我的噩梦,可是在学了automata之后,我知道DFA<==>DFS,他们对我来说是同样痛苦的记忆。我看了一晚上的<pretty woman>发现我实际上几乎没有从头看到尾过,这也许仅仅是感觉,而不是事实。也许因为,我不相信那后半段的神话,因为没有人相信,连导演都觉得太过分了,故意在结尾强调:This is Hollywood, a land of dream. 我们对梦想的态度也许都是近似的,正如在Julia Roberts的另一部超现实主义的浪漫剧<Notting Hill>中男主人公的经典台词:It is surreal, but nice。
田震的歌声配着我下午花了30个dollar买的speaker自有别样的韵味。在孤寂的,干燥的,寒冷的春夜里,我还毫无倦意,也许一颗心总在迷茫中漂泊。
三月八日 早上好象下雪了
去上totorial又在实验室里和angel研究明白了程序里的很多问题。现在好像对整个程序算是明白了,这算是编程还是猜字谜?不好意思就在贴一个版本,表示我今天并非无所事事一整天。翻出来以前的东西,作为我自己的理由吧。完成了一个简单的CPlayer的控制类,连同上一次做的CBag类总算可以算一个版本了。
三月十二日 晴朗的天空下大雪,这就是蒙特利尔的特色
上午阳光灿烂,我还和老张跑步去Maxi买菜,下午天空依旧晴朗,只是突然飘起了鹅毛大雪。奋战了好几天总算把一个初步的symbol-table做出了。我要说这个步骤对于compiler-compiler-writer来说都是最头疼的,因为,你看,作为scanner,parser我们可以做到完全的自动化,可是,这个时候,我不得不开始研究语法了。离开语法特征我完全无法知道该在什么时候作变量声明。当然,以我的意见,这就是之所以几乎所有的compiler-compiler都是LR的一个原因,因为,再LR里面的“状态”是非常有用的,而且你不会把原来输入的语法改的面目全非。我决定明天再作进一步的测试,现在保存一个版本吧?
朱春明同学的一句话叫我至今耿耿于怀:写程序本没什么了不起,惟手熟尔。这本来是我的原话,可是却听起来不那么顺耳,如果这样一言以蔽之,世间的万事万物岂不都是惟手熟尔?可是,客观地说,问题的复杂度一般都是不一样的,此惟手熟尔非彼惟手熟尔,正好像算法之间的复杂度的表示法中的big Oh一样,还是应该有所区别的。我无意贬低或抬高什么,(真的吗?人都有好恶的吧?) 也许其他人并不像我一样执著的相信人类的未来全部寄托在一些诞生不超过50年的“语言”的创作加工者身上。因为,也许人类的最终的解放就是彻底的自动化,其中的核心就是Intelligence Automation(I.A.)。也许A.I.这个词被用的太滥了,为了表示敬意,我创造一个新词来反用。这一切的一切就从编译器的自动化来开始吧?我想我在这个充满期待的即将到来的夏天应该能够写出一个完美的LR parser compiler吧?加上一个lex-like-scanner。这是一个多么让人激动地计划。但愿我不负了自己的誓约!
晚上没心情做别的事情就玩了会多线程,还是老问题,就是同步里的小问题,太简单了以至于我不好意思提出来,不过,我想我还是有可能犯错误的。同时对于windows上的多个线程的运行顺序感到不可理解。另一个奇怪的事情是SwitchToThread这个API明明在头文件里定义了,MSDN里也有,可是就是链接不上,后来我把api函数的定义拷过来,等于是直接调dll里面的api还是连接不上,说明dll里面确实是没有,window2000也是如此。看来只有问微软才知道了,该去那里问呢?
三月十三日 天气真冷啊,而我已经把厚衣服收藏起来了
早上调试我的compiler真是累啊,按照老师的意思是要彻底的测试,我这个project已经有四千行的代码了,有不少我现在都快忘了为什么那么写了,而这种语法测试实在是麻烦,首先你自己要知道结果吧?不然测什么?太累了,就和小邹去saint Laurence河边上去看冰层花了没有,真冷啊。下午去游泳,好久没有锻炼了,可能叫我游上一千米都会有些问题吧?屏气也坚持不了两分钟了。回来发现了scanner的一个大bug。不过,我觉得这个问题责任不全在我,因为老师当初没有说end of file也是一个token。否则我就不会这样出错了。如果以后要修改scanner的话,一定要记得。
三月十四日 天气还算晴朗
今天是Saint Patrick Day早上先把数码相机的电池充好电准备去看热闹。早上又在debug我的compiler,真是一个痛苦的过程,我想如果我当初能够用LR来写就不会这么写的ackward。还是留一个版本吧?
三月十六日 阴天
晚上上课回来偶然聊到《大话西游》因为我没有看过,感到有些遗憾没有机会了解现代的大学生的心态,所以就借来看看满足一下好奇心。当然是不明白所以然,本来也没有所以然,因为这正如P.P.所写的多线程程序一般充满了chaoes,一切都是只言片语,也许每一个场景都是刻意的塑造成永恒,而整个线索的无序成为事实上的无聊。因为,这也许正和激动的年代的躁动的脚步合拍。
昨晚和今天早上奋战完成了一些初步架构,保存一个版本吧?code generation摆在我面前的困难逼迫我要彻底地解决parser的问题,下个星期这是头号的任务。把昨天的小改动合并一个版本吧?
三月二十一日 阴晴不定
这几天事情不少,喜忧参半,烦恼不少。是否都要一一记录呢?summer research project算是一幢好事吧,去欧洲的旅费至少有了着落,word rover大致完工也算是一件高兴的事吧?因为我原来定下的目标就是这个周末完成。令人烦恼的还是操作系统这门课,哎!还有一些privacy的问题,真不知从何说起,欲说还休,不提也罢。
前天跑完步之后对springland的朱春明同学的居室进行了一次短暂的工作访问,对双方所共同关心的话题广泛深入地交换了看法,会谈的气氛是友好诚挚,会谈的结果是令双方所满意的。会谈所涉及的话题有就人类的认识发展与生物进化的关系,马克思主义哲学与形而上学之间的异同,离散数学在编译原理中的具体运用,自动机原理与算法理论等等,在相互的切磋探讨中进一步加深了彼此对客观世界的观点看法地了解,取得了广泛的认同,这次交流是一次有历史意义的盛会,双方都表示今后要定期举行此种交流,不妨成立一个名为springland-monk的合作组织,定期举行交流会。
保存wordrover的版本。
三月二十五日 小雨
好几天没有动笔了,或者说动手吧,因为,现在这学期所有的课程的作业都要电子版,几乎没有动笔的了。这几天也没有干成什么,除了改动了游戏的小bug什么也没有做,code generation的部分我还是没有开始,我又一次地陷入了这么一种困境,就是已经到达指定出发阵地,也接到了冲锋的命令却还不知道要向哪里进攻,甚至觉得连武器也没有找到。早上读了一遍moon machine的文档才略略明白了一点,我现在要产生的是intermediate code,不是什么真正的assembly code,只是一种自定义的类似p-code的代码,目标机器是一种想象的虚拟机,不过说想象也不对,因为,基本就是229里面定义的机器,而moon就是Dr. Grogono写的一个模拟器,我对他的敬仰又加深了一层。早上粗粗看了moon的源代码,又把范例的汇编码拿来编译运行,现在才真正有些明白了。模拟器人人都可以写啊!想起来当初在York旁听的时候偷偷下载的模拟器,当时觉得真是不可想象的神秘,看到是MIT的教授写的,就对MIT肃然起敬,现在想想Concordia的教授不也是能够做的吗?
常常地想,一个人每天头脑中的思虑何止百条,其中不乏真知灼见,甚至是灵感的火花,可是凭借常人的记忆有多少留了下来?过后回想起来总觉得如《围城》里面描述的,如同一个竹篮子去捞月亮,定神凝思总觉得就在那里,可是动起手来抓却都是空空如也。从前总觉得思虑如电,无数的华章美句在脑海里纷至沓来,但觉得伸手一抓,抓到哪一条都是挂一漏万,总想象着如果有一个agent环仕左右随时记录该有多好,现如今有机会及时纪录了,又发现经常头脑空空了。
三月二十八日 春光明媚
所以我就出去晒晒太阳。我看到的“冰河时代”以及“Saint Patric Day"。
心血来潮玩了会汇编,我常常想,假如我是生在dos时代的程序员我也许可以成为一个写汇编的专家吧?哈哈,我有点自不量力了,不过我觉得我确实对他独有情钟,可惜时间精力不允许我。记住编译的一个小错误:extrn声明部分是放在.code部分的!先编译/c,后用link链接都没有什么特别的。
三月三十日 蒙特利尔的春天终于来了
四月二日 阴雨绵绵
已经一个多星期了,我几乎昼思夜想穷尽心智以求一个解答,昨天再次去见Dr. Opatrny才算有一个方向了,我完全不必用stack去模仿function call。这实在是一个不能承受的工作量,不是说有多么复杂而是说我不可能又回到了“汇编”时代啊!实际上真像教授说得那样:“90%的工作量来自于code generation”。我又连续几天利用时间冥想准备,仿佛攻坚战之前的火力侦察,养精蓄锐终于决定今天早上发起进攻,初步决定准备付出一天的时间和牺牲100万脑细胞的代价扫清所有的外围阵地,包括必要的数据结构,状态控制方式,框架函数,并预留出最终代码产生所需的一些函数的calling位置。如果一切顺利明天发动总攻,后天写文档测试,星期一留半天机动作为总预备队,决心一定,依令执行!任务完成不了,各级指挥员剃头来见。(不过,前天我已经把头给剃了,哈哈,我发现男人的智商和头发的长度成反比,女人的柔情和头发的长度成正比,那位有意见不妨提出反例?)这一个星期没有写程序结果我全身上下都开始出问题了,首先是头疼,其次是脖子疼,晚上睡得少,下午睡的沉,天天头脑空空。。。
我最近眼神不好,也忘记怎么数数了。*_* ~_~ &_& :)
四月三日 天阴沉沉
战斗进行的异常艰苦,我从来没有遇到这样顽强抵抗的敌人,我的意思是说我现在已经把程序改的面目全非,简直惨不忍睹,现在根本不考虑什么效率与coding的艺术了,完完全全是白刃战肉搏战,所有的代码交织在一起,难分彼此,遍地是stack,不停地增加enum和struct,经常回过来在struct里面添加新的field。局部变量随处可见,全局变量已经到了命名的极限。战斗进行到这个阶段完全是一种胶着状态,唯一可能战胜敌人的武器就是指战员的意志和信念:Dr.Opatrny说过,if-statement是最复杂的,解决了他,就解决了一半。
战斗进展的很不顺利,我一方面根本不知道可能遭遇的困难,另一方面,每前进一步都是那么的艰难。
累死我了,眼睛都快睁不开了。没有完成既定的任务,不过在负出了惨重代价的同时,成功的攻克了if-statement。我实在太累了。
四月四日 又下雨了
现在是早上10点,六个小时以前我留下的一个版本还没有办法实现function call,现在依然不行,因为,参数的传递与检查是一个不容易的问题。一个人究竟需要多少时间来睡觉呢?
四月五日 又下雪了
人间四月芳菲尽,蒙特利尔飘雪花。昨天提前庆祝我的code generation大功告成,其实本来也没有什么,只不过我想给自己一些奖励罢了。于是,在肖邦的钢琴曲的伴奏下,油爆了一小盘冻虾,炒了一盘白菜,煮了一锅红豆稀饭,倒了一小小杯的8。99一升的干红,这样的生活真好啊。这样的生活不知道还有什么不满足的?今天打扫战场又改了不少的bug,就保存一个版本吧?或者说合并上一个版本。
四月七日 天晴但冷
改了很多的bug,并加了一个结束画面,现在可以把我的小成果给大家展示一下了。唯一可惜的是只能在win2000或win xp下运行。
四月八日 现在天还是黑的
昨天,Probst介绍了一个所谓的多线程算法---parallel-ranking-list,问题本身似乎没有什么实际意义只能作为多线程的练习,不过我还是想了半个晚上,因为,写c++习惯了总喜欢数数,不懂得应用已经获得的数据,也就是说,计算ranking的时候,你可以把你的后继的rank加到你自己rank里面,只要保证这同时,你的后继不再改动。其实这个同步问题还不如去计算一下pizza店里面多个server的队列的问题来的更有实际意义。
四月九日 晴天
花了一整天时间找我的wordrover的bug。现在这个版本算是完美版了吧?我把字典改成了可以增加的,也就是说每次运行前从dictionary.txt和readme.txt读入,运行完以后由存回dictionary.txt,这样我的字典可以越变越大,你不喜欢完整的字典吗?当然你不喜欢的话,你就把dictionary.txt删除或者改名,然后再readme.txt里面输入你喜欢的词。
四月十二日 大晴天
早上去跑步,中午去shopping算是负重急行军,回来后躺在场上让灿烂的阳光晒在肚皮上阵舒服,醒来后又去和小朱去跑步,这就是我的感恩节。应广大群众要求把comp346的所谓project贴出来,我实在觉得不好意思,如果被其他学校的人看到不定要怎样笑话Concordia呢。这也算是我一直藏拙的一个原因吧?这么一个简单的链表操作居然被冠以project的名目,真是让我等学计算机的人无地自容啊。教授不要脸面,学生还是要的。哈哈。。。复活节童言无忌了。
四月十三日 雨
应同志们的要求不敢藏拙,把我的346作业贴出来献丑了。另外这是课本的标准答案,使Laura发给我的,我想不能不与大家共享。还有probst在最后一堂课里讲到的考试范围,不过我的涂鸦可能连我自己都不一定看得懂,如果你不明白,再来问我吧?如果我也能看得懂的话。:) 1, 2, 3
四月十六日 好像夏天一样
一直盼望着夏天,可是当我们都能闻到夏天身上的气息的时候却又不知道要做什么了,只能到太阳下走走。编译器的战斗到了最后的阶段,不知道什么原因指战员有一点点厌战情绪,也许这个project远远超出了当初的预测,也许是前面两个阶段即symbol table和three-address-code做的非常不好使得我现在非常不容易进一步扩展,可能就像software engineering课程里软件扩展曲线变得非常陡峭,也就是说我现在没做一次扩展所要花费的时间精力正以几何级数增加。
四月十八日 又是阴晴不定
compiler这个project对一个人的编程的信心打击是最大的。我面对复杂的内存分配,终于开始后悔我当初想写一个完美的compiler乐。因为,人力有时有尽,对我来说记忆力下降到我对我的代码始终像是看天书,尤其对于在跟踪moon模拟器里的汇编码简直不知怎样入手,你看,我的compiler产生的汇编码我自己就看不明白对不对还要去内存里跟踪模拟器,到底谁对谁错我能清楚吗?现在我才真正体会到做一个现代的c++的程序员有多么幸福,因为在一二十年前编程是一件多么痛苦的工作啊,我对我自己在这么傻瓜化的vc下玩代码实在是要被人笑死了,当然,我去嘲笑玩VB,java的人的那种刻薄劲会一分不拉的被真正的高手还给我。世界之大真是超过我的想象力了,我现在觉得自己浅薄的如同台湾南部坐井观天的那帮农民了。数组对我是一个头疼的事,我初步想法试用类似于c面的指针一类的特殊变量来实现,这是一个复杂的问题,我不知道能不能行,在传参数里用真正的reference即地址和用stack传递value,最后在回写是各有利弊的,我不觉得我现在的传地址的方案有什么原则上的失误,当时对于数组我却始终没有想出好办法,229里面有专门的寄存器来记录index,而我却想不出怎样模拟。现保存一个版本吧?我对code generation部分非常得不满意,决定将其等级将为一颗星。 moon machine的模拟器在这里。
四月二十日 有雨
总算完成了绝大多数的功能,这一直都是我不敢相信的!我不敢相信这是真的,经过了这么多的磨难好像唐僧去西天取经经过了八十难,不知道那最后一个磨难会在什么时候出现,最好是越早发现越好。我的这个project充满了遗憾与不足,假如能让我从来过,我一定要把scanner与parser一同来写;我一定要用LR(1)来写;我一定要把code generation部分分离出来;我一定要临时变量重复使用stack里的地址;我也许要使用类似于passing by value的方式,因为,这给了module里面的数据的独立性,如果,要passing by reference就简单地pop回原来的地址,因为,绝对的passing by address是一个非常危险的方式。我也许要彻底引入指针变量,而不是像现在这样似是而非;我也许想要解决label的问题,因为,并非所有的汇编器都这样的支持label吧?总而言之,是否用3-address-code的中间代码是一个值得考虑的问题。我要重新设计我的中间代码指令集。明天,不,应该是今天要继续作大量的测试,同时争取把报告的结构理出来。教训就是:never underestimate the difficulty!这个问题再写我的word rover就已经遇到过了,我当时还希望加入华丽的图形界面,多种选项,甚至A.I.。结果全都是不切合实际的。现在我已经根本不奢望提前demo了,能够不出现问题就谢天谢地了,看着我的那个乱七八糟的parser+code gengerator部分,我经常不敢相信这是我写的,因为我经常看不懂,不过,后来当我穷经皓首地调试跟踪汇编码的时候,我开始羡慕调试c++程序了,毕竟那是比较接近人的思维的吧。保存一个版本。
对了,前两天收到不知名的美国的一个大概是college的学生发的邮件央求我替他做project,大概是一个min-max-heap的数据结构的东西,虽然我很有兴趣,实在是没有时间,而他的due date比我的还早,只好婉言谢绝了,毕竟人家透过google找到我这里不容易啊。而且这家伙网页做的挺漂亮的。现在敝人在google上也是榜上有名的,不信把我的大名输进去查一下,哈哈。。。自我陶醉一下吧,在这个温暖的春夜里听梁咏琪的歌曲很有一些情调的。
四月二十一日 晴朗的天空好像蓝色果冻,白云好像棉花糖,我有点饿了
其实,现在天空是黑黑的,离天亮还有好几个小时呢,我奋战了一晚上才找到递归调用的问题,其实并不是我所担心的是栈的问题,恰恰是我从没有想到的条件转向语句的问题。if-then-else,loop-end都有小问题,等我发现这种错误,我已经跟踪那天书一般的汇编不知多少回了。随便几行代码,汇编就是上百行,我看的头昏脑胀,因为,并不知道问题是编译环节有好几层,我再不能确定问题出在那里的时候,找起来真是困难。现在总算解决了,至少看上去是这样,fibonacci,factorial 之类的经典递归功能都可以了。我也快累死了。就让我在梁咏琪的歌声中留一个版本吧?
明天就要交报告了,我在梁咏琪青春靓丽的歌声中回顾我的日记中关于编译器的部分,突然才意识到它是这么的漫长,我从严寒的冬天一直写到春暖花开的季节,断断续续的有四个月了,粗略统计可能有近六千行代码吧?实际上当然包括不少的注释,和comment掉的代码,不过这些部分表示实际的工作量要比这多得多,因为,一方面改错绝对是很辛苦的一件事,费的时间更多,另一方面我想有关语法的注释可能比代码部分更难懂吧?如果你没有学过parsing的话。回顾这中间的苦乐酸甜,真是一种令人难忘的经历,正如歌曲里唱得那样:突然之间翻到了小说结尾的那一章,我想我不但要给教授一个report,也要给自己打一个分数吧?如果要打分的话,那就给个75分吧?因为,这是从我付出的努力来着眼的,毕竟从最初写语法阅读器有很多intuitive的成分,从这一点出发,我对自己还是满意的,这之前我并不明白什么是compiler-compiler,只是从直觉出发,抛开所有的工作不提,我想我应该给自己这个分数。教授给我多少分,我倒是不太在乎了,只要我学到了我想要得,还计较什么?至少我想我会有一点可能比班上其他人写得多一点点,或者真实一点点,那就是报告的最后一部分,wish-list或者一个what-if或者一个if-only-list。我在这门课程上投下了这么多的心血,同样也得到太多的遗憾与不满。假如让我重头来过,我会。。。
人生也许就是这样,假如。。。我会。。。我会吗?
四月二十五日 晴间多云
O.S.实在是一件无聊的