[编译原理读书笔记][第4章 语法分析]
标签(空格分隔): 未分类
首先介绍概念,然后介绍适合手工实现的技术,最后介绍用于自动化的工具的算法,然后因为经常包含语法错误,讨论如何扩展语法分析方法,以便从常见错误中恢复.
- 文法给出了一个程序设计语言的精确易懂的语法规约
- 对于某些类型的文法,我们可以自动的构造出高效的语法分析器
4.1 引论
4.1.1 语法分析器的作用
语法分析器的作用是构造出语法分析树
- 实际上,并不需要显式地构造,如之前几章看见,使用动作,可以跟语义分析和中间代码生成结合成一个模块.
处理文法的语法分析器大体上可以分为三种类型的:通用的,自顶向下的,自底向上的
- 通用的:
Cocke-Younger-Kasami
算法,Earley
算法,效率很低. - LL 手工
- LR 自动
- 通用的:
4.1.2 代表性的文法
主要关注表达式,因为运算符的优先级和结合性,使得表达式的处理更具挑战性.
(4.1)
- 属于LR文法,适用于自底向上的语法分析技术.
- 经过修改能处理更多优先级
- 不能用自顶向下,因为是左递归的.
下面给出无左递归版本. (4.2)
在给出一个具有二义性的文法,将来用于说明语法分析过程处理二义性的技术
4.1.3 语法错误的处理
本节将考虑语法错误的本质,以及错误恢复的一些策略,
- 其中两种策略被称为恐慌模式,短语层次恢复,
- 将和特定的语法分析方法讨论
程序有不同层次的错误
- 词法错误:标识符,关键词拼写错误,没有在字符串文本加入正确的引号.
- 语法错误: 分号放错地方,括号不匹配.
- 语义错误: 运算符和类型的不匹配
- 逻辑错误: 比如要使用
==
地方,使用=
语法分析方法的精确性让我们能高效检测语法错误,有些语法分析方法,比如LL
和LR
方法,都能第一时间发现错误.
- 编译的时候,语义错误和逻辑错误很难被发现.
语法分析器的目标简单,但是实现很麻烦.
- 清晰精确的报告出现的错误
- 尽快从错误中恢复,检查后面的错误.
- 尽可能少的减少检测正确程序的开销.
4.1.4 错误的恢复策略
- 比较普遍的想法是检测到错误就退出.
- 比较高级的想法是从错误中恢复,以检查后面更多的错误.
恐慌模式的恢复
- 使用这个方法,语法分析器一旦发现错误就不断丢弃输入中的符号,一次丢弃一个,直到找到同步词法单元集合中的某个元素.
同步词法单元
通常是界限符,比如分号和{
.- 编译器的设计者,必须挑选适当的界限符.
- 恐慌模式会跳过大量输入.
- 但是他很简单,且不会陷入无限循环.
短语层次的恢复
- 当发现一个错误的时候,语法分析器可以在余下的输入上进行局部性纠正
- 常用的纠正方法包括将一个逗号替换为分号
- 删除一个多余的分号,或者插入一个遗漏的分号.
- 小心使用替换,以免无限循环
错误产生式
- 文法加入特殊的产生式
全局纠正
- 通过某种算法,寻找一个最合适的纠正
- 开销很大,只具有理论价值
4.2 上下文无关文法
4.2.1 上下文无关文法的正式定义
- 一些关于终结符号,非终结符号的定义就不写了.重在意会.
- 产生式的
->
有时也可用::=
来代替
4.2.2 符号表示的约定
本书对文法的约定
- 没什么好做笔记的..
4.2.3 推导
将产生式看做重写规则,就可以从推导的角度精确描述构造语法分析树的方法.
从开始符号出发,每个重写步骤把一个非终结符号替换为他的产生式的体.
- 这个推导思想对应于自顶向下构造语法分析树的过程.
自底向上语法分析和一种被称为最右推导的推导类型相关.
- 在这种推导过程,每一步重写