追寻真理之美

——此人一贯挖坑不填

用户操作
[即时聊天] [发私信] [加为好友]
智拙ID:ccat
108954次访问,排名856,好友0人,关注者7人。
ccat的文章
原创 66 篇
翻译 4 篇
转载 0 篇
评论 88 篇
智拙的公告
Python 2.4
最近评论
zhangjunhd:理解
ccat:错误我改过来了,PDF版和TeX版文件也重新上传了,但是HTML压缩包不知道怎么删除重新上传。
ccat:多谢提醒,我晚上回去看看。
ccat:杨编辑好:)
linux:嘿嘿,刘鑫老师,我是博文的linux!
文章分类
收藏
    相册
    文章插图
    朋友
    bobo,家有三猫
    Fire,永远比我严肃那么一点点
    lee
    limodou,NewEdit之父(RSS)
    Playyuer,近来可好(RSS)
    Ricky的私人领地
    Vicko,聪明的孩子,提着易碎的灯笼
    Vickox,一个人,两枝笔
    冰菊叮叮的绮季
    卡卡和哆哆的小窝,从这里开始,我的人生不再与以前相同
    寻梦的blog
    小尹,成功人士将来时。
    岑心的小天地
    暖暖,美丽的文字,总是让我深陷其中。
    梅劲松,Python经典实践(RSS)
    欢欢小师妹(RSS)
    灰色咆哮,彩色收藏
    蔚蔚,祝你幸福快乐
    西区故事,有故事的男人。
    面面的金鱼缸,内有美人鱼,生人勿近
    饼干~大饼~素饼饼~
    收藏
    cavingdeep,颇有知音之感(RSS)
    Guoly工作室,提供WinCVS中文教程
    Robert Chen(RSS)
    深入浅出,诲人不倦,可为人师也——项武义先生网站
    透明,熊节
    网络项目
    .net 中文讨论组
    Firebird项目的CVS
    Python2.3指南
    Python中文社区
    Python文档中文化项目
    啄木鸟
    啄木鸟的老巢
    我的新家
    休闲收藏
    办公室Party
    廖添丁
    恶搞圣斗士
    魔塔
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 表达式解析趣谈收藏

    新一篇: 数组移动算法 | 旧一篇: CLIST Tutorial中英对照版(二)

    代码的编译是计算机科学的一大命题,其博大精深,难以尽数。这里,我们捡着一个小命题娱乐一下。
    程序代码中,总是少不了数学运算,其实对于我们来说很熟悉的数学计算,在计算机里也是要做一些编译处理的。
    例如,4+9*3+7-2这样一个简单的四则运算,对于人来说就是:
      4+9*3+7-2
    =4+27+7-2
    =31+7-2
    =38-2
    =36

    这里面,我们实际上已经在下意识里做了很多思考。首先,大脑会按照运算符划分开各个子算式,然后找出运算优先级的子式,按顺序计算完后,将结果填充给下一级,依次递归,直至整个算式完成。
    计算机的编译/解释过程,其实跟这个很像,也是先找出最高优先级的子式,然后依次递归构造出一个语法解析树,调用数学运算指令计算每个节点,返回结果。对于每个单步运算,计算机里面调用一次+、-、*、/的时候,其实是一次函数操作,每个运算符执行对应的函数,比如1+1,其实就是+(1, 1)。在编译时,通常会把这样的运算翻译为后缀表达式,+(1, 1)就变成了1 1 -,这样的好处是计算机逐次读入每一个词,遇到操作数就压栈,遇到操作符就把所需个数的操作数从栈里弹出来计算,然后再把结果压进去,这个过程以轻松匹配复杂表达式。不过——这么看起来是不很累?特别是复杂算式,就看不清层次了。我们把它用括号包起来,就成了(1 1 -),这样清晰一些了吧,我们现在按这种方式把开头的那个式子写成
    (((4 (9 3 *)+) 7+) 2 -)
    现在,我们用一个[]表示堆栈,左边是栈顶,右边是栈底。现在我们模拟计算机的解释过程。
        (((4 (9 3 *)+) 7+) 2 -)
    =>[4]                            4入栈
    =>[9 4]                         9入栈
    =>[3 9 4]                      3入栈
    =>* (9 3) [4]                  读到*,弹出最上面两个数3和9——需要注意,因为堆栈的后入先出特性,实际上栈顶的元素反而在参数表的右边
    =>[27 4]                       把相乘以后的结果27重新压入栈
    =>+ (4 27) []                 读到+,弹出最上面两个数27和4
    =>[31]                          把相加结果31入栈
    =>[7 31]                        7入栈
    =>+ (31 7)[]                  读到+,弹出最上面两个数7和31
    =>[38]                          把相加以后的结果38入栈
    =>[2 38]                       2入栈
    =>- (38 2)[]                   读到-,弹出最上面两个数2和38
    =>[36]                          把相减结果36入栈
    =>36                            检测到运算过程已经完成,把结果从堆栈中弹出返回

    以上这个过程对计算机是很方便,但是对于我们读起来还是有点别扭,把运算符放前面不是更好懂么?编译原理中,前缀表达式也是一种常见的写法,于是:
    (((4 (9 3 *)+) 7+) 2 -)=>(-(+(+ 4 (* 9 3)) 7) 2)
    这个么,应该有朋友已经发现了,这不就是一段LISP代码么?!
    我有很长时间不能很好的理解LISP代码,直到有位朋友说,LISP就是语法解析树的前缀表达……
    以此文向他致敬!

    发表于 @ 2006年04月03日 22:35:00|编辑

    新一篇: 数组移动算法 | 旧一篇: CLIST Tutorial中英对照版(二)

    评论:没有评论。

    Csdn Blog version 3.1a
    Copyright © 智拙