编译原理及实践

作者:Kenneth C.Louden

机械工业出版社

出版年:2000-3-1

综合评分:7.0

_________________________

果然如网上流传的那样,翻译的真是和google有的一拼。难得这么一本很重实践的编译原理书,就这样被翻译打了折扣。反过来说,如果真的用心看,翻译的结果无非是英式文法的中文,要看也是可以看得了。这是苦了我们反复推敲语义,这种阅读实在不爽。问题终归问题,对于我这个自学者来说,这是难得的好教材,结合c代码一步一步的讲解,让读者把握哪些是真正的重点,哪些是实现的关键。我觉得这样对于自学者速成确实是很有帮助的。反之,看那本“龙书”,对于初学者抑或自学者确实有点难度。

 
最 近重新阅读《编译原理》,当初的认识仍然很浅薄,书评也写得幼稚,如今又有些新的体会在此列出:
1. 语法分析的目标是构建语法树,因为计算机常用的运算是二元运算:加减乘除等等,因此构建的结构是一个二叉树。同时,我们根据二叉树的遍历等等一些知识,可以认为语法分析的任务就是根据树的遍历结果(程序代码或表达式)重新构建树;另外,我们知道我们给计算机的表达式的方式是带有二义性的,必须定义算符的优先级以及结合规律方可以回避二义性。考虑a+b*c,可以翻译为(a+b)*c或者a+(b*c),因此我们的常规表达方法为回避这些问题,必须要带有"(",")",当然我们所说的常规表达式就是对语法树的中缀遍历结果。那么,如果考虑计算机的计算模型是基于栈和寄存器的方式,显然适合人类读写的中缀表达并不适合计算机理解运算,因此我们意外的发现,波兰式以及逆波兰式(对应对语法树的前序遍历以及后序遍历)十分适合现代计算机的实现,而且他们的最大优点就是不需要括号以及优先级,特别适合栈和寄存器计算模型去实现。综上所述,语法分析的任务(显然我们将代码生成也并入了,不过为了说明主旨)就是根据适合人类读写的表达式(中序遍历)重构完整的语法树,并转化成适合计算机模型计算的波兰式或者逆波兰式(对应于前序遍历以及后续遍历);当然在编译器实现中,我们并不需要真的必须构造一个语法树实体。
 
2. 理解语法分析的难点往往集中在对 上下文无关语言、栈、树等知识的理解上。形式语言无需再讲,对于下推自动机等等已经在算法笔记上有所涉及,这里主要讲一讲,为什么出现LL,LR这两种不同的语法分析方法。首先从语法分析的本质结构:二叉树出发,我们知道对于树的处理很多是基于其独有的递归特征进行展开的,这一点体现在对树的遍历、旋转等等操作上,一般而言,我们可以通过 自顶向下 以及 自底向上 两种方式去访问和处理树结构,例如在实现计算典型的树形结构问题Fibonacci数列计算问题的时候,既可以设计递归计算程序,也可以反过来设计递推程序一样,这就对应了实现方式的不同,递归对应自顶向下,而递推对应自底向上方式。同样道理,LL以及LR就分别对应自顶向下以及自顶向上方式去访问树结构。
 
3. 这里有人要问,一般树都会讲两种自顶向下语法分析方法:递归下降以及LL;他们又是什么关系呢?这一点就要从递归的实现说起,我们知道递归必将显式或者隐式的实用栈结构,这是我们理解的基本出发点。当然,我们仍是采用自顶向下的方式去求解问题,这一点要和递推(自底向上)区分。对于递归程序,系统已经帮助我们将函数的调用完成,其本质也就是一个压栈出栈的过程,只是这些是我们看不到的。反之,如果我们构造栈结构,模拟这个过程,那么就可以将递归去除,这也是为什么对于很多问题(如八皇后问题)往往即有递归算法又有非递归算法的原因。那么,我们现在清楚了,递归下降算法就是一种隐式的栈实现,而LL就是显式的栈实现。
 
4. 补充说明1:自顶向下代表的是对树结构的前序遍历,而自底向上代表后序遍历(注:这种说法并不严谨,但是辅助理解还是有益的)。
_________________________
2010.11.6
最近的学习和阅读中,特别是理解动态规划的两种实现:递归以及递推上。我有发现了top-down以及bottom-up设计方法[wiki]和编译原理的语法分析以及程序设计的哲学的联系,其本质都是针对树结构的特点。自顶向下的分析方法[ref],掌控全局,对全局的功能实现做一个推断,继而细化至每一个子模块,重复这个过程直至足够细或者不能划分为止(即递归的base case或者数学归纳法的基本情况),这种方式显然要求设计师拥有足够的信息和知识、全局的洞察力和分析能力;自底向上方法[unix]鼓励设计师设计基本元素,继而将这些基本元素组合起来,也要依赖于设计师丰富的经验,并且如何设计基本元素显然是一个精益求精提炼的探索过程,当然优点就是一旦提炼出这些基本的组件和元素,重用非常的方便。当然,在实际中这两种方案往往是混合使用的。对于自顶向下来说,将系统划分成独立的模块显然在实际中并不总是有效(因为很难将各个模块设计到完全独立,往往各个模块需要调用相同的东西:类似于动态规划的子问题重复性),特别是软件工程上强调的可重用性:回顾软件设计的发展,从早期的自顶向下典型:面向过程式设计方法要求划分程序的模块,实现各个过程,面临着不可重用的困境,直到面向对象出现,强调设计出元组件(这些元组件可以方便的移植到不同的模块),在拼装成复杂的模型,大大提高了软件的可重用性以及开发效率。当然,两种设计方法在实践中都是非常重要的,各有优缺,单纯的一种开发模式是不可取的。
_________________________
2010.12.05
 
上面的部分主要讲解的都是词法分析和语法分析的内容,在编译领域,我们统称这两种法则为文法。有了文法就有了语言,但是我们仍然有重要的一步:语义分析。任何一门编译原理的书中,语义分析都是重点,通常来说,读完了艰深的词法分析和语法分析后,面对的语法分析同样是一个挑战。语义分析的内容很多,同时它也是后续产生中间代码生成的必须过程。简单的来说,我们可以将语义分析理解成如何根据上述两个过程得到的语法树进行标注。这个标注我们称作属性,其实这个属性包含的东西很多,可以说变量以及过程的各种信息:名称,值,类型等等,我们都可以称之为属性。看来若我们把语法树的信息都合理有效的标出来了,那么似乎我们已经把语句信息合理的分析出来了,剩下的工作也就可以顺利的开展了。
这里就需要注意一个理解的要点:属性可以分为综合属性以及继承属性这两种。在语法树上理解的话,我们可以理解为综合属性是需要了解子节点的属性才可以得到父节点的属性,这相当于一个自底向上的过程;而对于继承属性,则意味着我们必须先知道父节点的属性或者其兄弟节点的属性才可以判断其属性,这相当于一种自顶向下的思路。当然这种规定仍然对我们的编译器实现仍很复杂,于是我们规定了两种属性法则:S属性文法与L属性文法;对于前者,我们了解其只包含综合属性;而后者并不是只包含继承属性,而是包含一种特殊的继承属性和若干的综合属性构成的属性文法。这种特殊的继承属性是一种节点只会继承其父代或者最左面的节点属性的规定,其实这个我们的语句书写有关,因为我们总是规定先访问左边的节点后才会访问右边的若干节点。
属性这个词往往比较抽象,这是为了教授研究而进行的泛化;其实在编译器中我们最关心两个重要的属性:类型和值。对于类型这个属性来说,其可以是继承的,也可以是综合的。而且类型关系到我们的语义的正确性:例如我们总不能让一个浮点数做数组的下表吧,应当在语义分析部分对类型进行检查。
______________________________
2011.3.8
 

编译原理及实践

作者:Kenneth C.Louden

机械工业出版社

出版年:2000-3-1

综合评分:7.0

_________________________

果然如网上流传的那样,翻译的真是和google有的一拼。难得这么一本很重实践的编译原理书,就这样被翻译打了折扣。反过来说,如果真的用心看,翻译的结果无非是英式文法的中文,要看也是可以看得了。这是苦了我们反复推敲语义,这种阅读实在不爽。问题终归问题,对于我这个自学者来说,这是难得的好教材,结合c代码一步一步的讲解,让读者把握哪些是真正的重点,哪些是实现的关键。我觉得这样对于自学者速成确实是很有帮助的。反之,看那本“龙书”,对于初学者抑或自学者确实有点难度。

 
最 近重新阅读《编译原理》,当初的认识仍然很浅薄,书评也写得幼稚,如今又有些新的体会在此列出:
1. 语法分析的目标是构建语法树,因为计算机常用的运算是二元运算:加减乘除等等,因此构建的结构是一个二叉树。同时,我们根据二叉树的遍历等等一些知识,可以认为语法分析的任务就是根据树的遍历结果(程序代码或表达式)重新构建树;另外,我们知道我们给计算机的表达式的方式是带有二义性的,必须定义算符的优先级以及结合规律方可以回避二义性。考虑a+b*c,可以翻译为(a+b)*c或者a+(b*c),因此我们的常规表达方法为回避这些问题,必须要带有"(",")",当然我们所说的常规表达式就是对语法树的中缀遍历结果。那么,如果考虑计算机的计算模型是基于栈和寄存器的方式,显然适合人类读写的中缀表达并不适合计算机理解运算,因此我们意外的发现,波兰式以及逆波兰式(对应对语法树的前序遍历以及后序遍历)十分适合现代计算机的实现,而且他们的最大优点就是不需要括号以及优先级,特别适合栈和寄存器计算模型去实现。综上所述,语法分析的任务(显然我们将代码生成也并入了,不过为了说明主旨)就是根据适合人类读写的表达式(中序遍历)重构完整的语法树,并转化成适合计算机模型计算的波兰式或者逆波兰式(对应于前序遍历以及后续遍历);当然在编译器实现中,我们并不需要真的必须构造一个语法树实体。
 
2. 理解语法分析的难点往往集中在对 上下文无关语言、栈、树等知识的理解上。形式语言无需再讲,对于下推自动机等等已经在算法笔记上有所涉及,这里主要讲一讲,为什么出现LL,LR这两种不同的语法分析方法。首先从语法分析的本质结构:二叉树出发,我们知道对于树的处理很多是基于其独有的递归特征进行展开的,这一点体现在对树的遍历、旋转等等操作上,一般而言,我们可以通过 自顶向下 以及 自底向上 两种方式去访问和处理树结构,例如在实现计算典型的树形结构问题Fibonacci数列计算问题的时候,既可以设计递归计算程序,也可以反过来设计递推程序一样,这就对应了实现方式的不同,递归对应自顶向下,而递推对应自底向上方式。同样道理,LL以及LR就分别对应自顶向下以及自顶向上方式去访问树结构。
 
3. 这里有人要问,一般树都会讲两种自顶向下语法分析方法:递归下降以及LL;他们又是什么关系呢?这一点就要从递归的实现说起,我们知道递归必将显式或者隐式的实用栈结构,这是我们理解的基本出发点。当然,我们仍是采用自顶向下的方式去求解问题,这一点要和递推(自底向上)区分。对于递归程序,系统已经帮助我们将函数的调用完成,其本质也就是一个压栈出栈的过程,只是这些是我们看不到的。反之,如果我们构造栈结构,模拟这个过程,那么就可以将递归去除,这也是为什么对于很多问题(如八皇后问题)往往即有递归算法又有非递归算法的原因。那么,我们现在清楚了,递归下降算法就是一种隐式的栈实现,而LL就是显式的栈实现。
 
4. 补充说明1:自顶向下代表的是对树结构的前序遍历,而自底向上代表后序遍历(注:这种说法并不严谨,但是辅助理解还是有益的)。
_________________________
2010.11.6
最近的学习和阅读中,特别是理解动态规划的两种实现:递归以及递推上。我有发现了top-down以及bottom-up设计方法[wiki]和编译原理的语法分析以及程序设计的哲学的联系,其本质都是针对树结构的特点。自顶向下的分析方法[ref],掌控全局,对全局的功能实现做一个推断,继而细化至每一个子模块,重复这个过程直至足够细或者不能划分为止(即递归的base case或者数学归纳法的基本情况),这种方式显然要求设计师拥有足够的信息和知识、全局的洞察力和分析能力;自底向上方法[unix]鼓励设计师设计基本元素,继而将这些基本元素组合起来,也要依赖于设计师丰富的经验,并且如何设计基本元素显然是一个精益求精提炼的探索过程,当然优点就是一旦提炼出这些基本的组件和元素,重用非常的方便。当然,在实际中这两种方案往往是混合使用的。对于自顶向下来说,将系统划分成独立的模块显然在实际中并不总是有效(因为很难将各个模块设计到完全独立,往往各个模块需要调用相同的东西:类似于动态规划的子问题重复性),特别是软件工程上强调的可重用性:回顾软件设计的发展,从早期的自顶向下典型:面向过程式设计方法要求划分程序的模块,实现各个过程,面临着不可重用的困境,直到面向对象出现,强调设计出元组件(这些元组件可以方便的移植到不同的模块),在拼装成复杂的模型,大大提高了软件的可重用性以及开发效率。当然,两种设计方法在实践中都是非常重要的,各有优缺,单纯的一种开发模式是不可取的。
_________________________
2010.12.05
 
上面的部分主要讲解的都是词法分析和语法分析的内容,在编译领域,我们统称这两种法则为文法。有了文法就有了语言,但是我们仍然有重要的一步:语义分析。任何一门编译原理的书中,语义分析都是重点,通常来说,读完了艰深的词法分析和语法分析后,面对的语法分析同样是一个挑战。语义分析的内容很多,同时它也是后续产生中间代码生成的必须过程。简单的来说,我们可以将语义分析理解成如何根据上述两个过程得到的语法树进行标注。这个标注我们称作属性,其实这个属性包含的东西很多,可以说变量以及过程的各种信息:名称,值,类型等等,我们都可以称之为属性。看来若我们把语法树的信息都合理有效的标出来了,那么似乎我们已经把语句信息合理的分析出来了,剩下的工作也就可以顺利的开展了。
这里就需要注意一个理解的要点:属性可以分为综合属性以及继承属性这两种。在语法树上理解的话,我们可以理解为综合属性是需要了解子节点的属性才可以得到父节点的属性,这相当于一个自底向上的过程;而对于继承属性,则意味着我们必须先知道父节点的属性或者其兄弟节点的属性才可以判断其属性,这相当于一种自顶向下的思路。当然这种规定仍然对我们的编译器实现仍很复杂,于是我们规定了两种属性法则:S属性文法与L属性文法;对于前者,我们了解其只包含综合属性;而后者并不是只包含继承属性,而是包含一种特殊的继承属性和若干的综合属性构成的属性文法。这种特殊的继承属性是一种节点只会继承其父代或者最左面的节点属性的规定,其实这个我们的语句书写有关,因为我们总是规定先访问左边的节点后才会访问右边的若干节点。
属性这个词往往比较抽象,这是为了教授研究而进行的泛化;其实在编译器中我们最关心两个重要的属性:类型和值。对于类型这个属性来说,其可以是继承的,也可以是综合的。而且类型关系到我们的语义的正确性:例如我们总不能让一个浮点数做数组的下表吧,应当在语义分析部分对类型进行检查。
______________________________
2011.3.8
 

读书笔记(II) 编译原理及实践相关推荐

  1. PL/0语言编译器扩展 编译原理课程实践(1)

    转眼大学生活就要结束,编译原理课程学的东西很多都忘记了.当时我们编译原理课程实践是PL/0语言编译器扩展,在原有PL/0语言文法进行扩展.我写这次博文一是为了回忆以前学的知识,加深记忆:二是和大家分享 ...

  2. 《统计学习方法》读书笔记——感知机(原理+代码实现)

    传送门 <统计学习方法>读书笔记--机器学习常用评价指标 <统计学习方法>读书笔记--感知机(原理+代码实现) <统计学习方法>读书笔记--K近邻法(原理+代码实现 ...

  3. 【读书笔记】金字塔原理-构建金字塔的逻辑顺序

    至此,我们已经学会了如何搭建文章的总体架构.我们可以较快的确定文章的主题和读者可能提出的疑问,编辑好序言(开场白)中的"背景"和"冲突",提出问的中心思想和关键 ...

  4. 读书笔记: 经济学原理

    读书笔记: 经济学原理 学习笔记: 经济学原理 preface 学习经济学的一些知识. content 经济学简介 什么是经济学 经济学不能赚钱的, 但是能让你理解政府的决定, 公司的决定, 社会的决 ...

  5. c语言链表单值化,《编译原理及实践教程》第3章词法分析.ppt

    <编译原理及实践教程>第3章词法分析 方法如下: 正规式R?有穷自动机NFA M ? s,t是正规式,相应NFA为N(s),N(t),则正规式R=s|t,构造NFA(R) 为: ? 对应正 ...

  6. 编译原理课程实践——实现一个初等函数运算语言的解释器或编译器

    编译原理课程实践--实现具有初等函数运算语言的解释器或编译器 作者:Sylvan Ding |转载请注明文章出处! 摘要:本文主要内容是设计词法分析器.语法分析器(LL(1).SLR(1))和语义分析 ...

  7. 国内外编译原理课程实践教学现状分析

    <自己动手写编译器.链接器> 冯向萍 (新疆农业大学计算机与信息工程学院)   摘 要:本文主要从教材的选择,实践项目的设置以及实践课程占总评成绩的比例等方面分析和比较了国内外多所高校编译 ...

  8. 读书笔记|《金字塔原理》_第一章

    读书笔记|<金字塔原理>_第一章 [章节]--第一章为什么要用金字塔结构 [讲了什么] 1.首先是为什么要用金字塔结构? 2.如何将思想组织成金字塔结构? 2.1 归类分组,将思想组织成金 ...

  9. 【读书笔记】金字塔原理-构建金字塔的思维方式

    经过了上一章节的概念轰炸,你可能开始困惑到底我们到底要干什么了.所以在介绍如何构建金字塔之前,我们先尝试回答一个问题,为什么我们要构建金字塔? 金字塔能帮助读者尽快的理解我们想表达的思路. 而理清思路 ...

最新文章

  1. 【建模必备】遗传算法的基本原理与步骤(变异)
  2. 生命天书”破译20年,生命科学由此走向“大数据时代”
  3. vb.net 正则 替换 第n个_Python中正则表达式模块详解
  4. .NET中Flags枚举的使用
  5. 机器学习实战-第二章代码+注释-KNN
  6. Linux平台常用命令
  7. 未来函数在线检测_嵌入式实时操作系统任务栈溢出检测原理
  8. 的c语言_什么是C语言?C语言的简介
  9. Qt实现Linux下模拟点击界面,如何利用QT实现模拟鼠标点击?
  10. 信息产业浪潮中,京东 IoT 的技术演进与实践创新
  11. Cplex入门教程(一)
  12. RINEX格式文件内容解读
  13. h5抽奖大转盘开发笔记小结,涉及到的知识点和包资源
  14. 早餐吃菠萝好吗 早上可以吃菠萝吗
  15. mysql ibd 恢复_MySQL:如何从ibd文件中恢复数据
  16. ps计算机海报设计,海报设计(ps标准平面海报设计尺寸一般多大)
  17. 2020福州大学计算机录取名单,福州大学数学与计算机科学/软件学院2020年硕士研究生招生复试结果(第二批非全日制公示)...
  18. 疫情之下:如何高效远程办公
  19. AT89S8253片内EEPROM字节读、字节写、页读、页写驱动代码、注意事项及注释
  20. Css3之画哆啦A梦

热门文章

  1. 鸿蒙一青城的对联,8副写景色的对联,风景美如画,令人陶醉!
  2. Java实现包含多级目录文件的筛选删除操作
  3. HDU6143 Killer Names(数论)
  4. 手办商城app开发功能分析
  5. 编辑器下运行exe或bat run exe or bat in editor
  6. 从MSYS2访问Windows目录
  7. c4d里.gil和.gi2是什么文件?怎么打开
  8. 仿权重8高收录面包网pc+手机苹果cmsv8影视网站含迅雷下载N430模板
  9. 2020-2021年度第二届全国大学生算法设计与编程挑战赛题解(冬季赛)
  10. 使用Blinker+ESP8266接入天猫精灵