词法分析的任务
- 分析从词法分析获得的token在程序中扮演什么juese
- 检查语句或者程序是否符合程序语言的语法。
一个上下文无关文法(CFG)组成部分
- 终端符号(terminal)的集合T
- 非终端符号的集合N
- 唯一的开始符号S
- 产生式
为什么CFG的能力比正则表达式强?
因为CFG允许递归定义
练习:
用上下文无关文法定义下列语言。
(1)
S->0S1|01
(2)只含有0和1的回文串
(3)只含有(和)的匹配括号串
最左推导:每次推导都替换最左边的非终端符号
最右推导:每次推导都替换最右边的非终端符号
文法的二义性:如果对于一个文法,存在一 个句子,对这个句子可以构造两棵不同的分析树(一般来说如果有对称的推导式,那么这个文法一般来说就是二义性的)
例子:
每个能用正则表达式的语言一定能用上下文无关文法来表示,反之不成立。
正则表达式(NFA和DFA)与右线性文法的表达能力是等价的。
因为一个左递归的文法会使它的递归下降语法分析器进入无限循环,所以我们需要进行左递归的消除。
消除立即左递归
消除左递归
例子:
提取左公因式:找出生成式中的最长公共前缀,合并之,不同后缀部分用一个新的非终端符号表示
为什么需要提取左公因式:因为全部回溯的效率太低了。(剪枝)
但是单纯的提取左公因式的效果还是太局限了。
就我看来,加上了预测表其实就是剪枝了。
对于LL(1)文法(第一个L是指从左到右,第二个L是指产生最左推导)
那么如何构造这个预测表呢?
需要用到两个函数
first(A) 是指可由 A 导出的串的首终端符号的集合(含 ε)
FOLLOW(A) 定义为可能紧跟在 A 右边的终端符号的集合,不含 ε,但包含字符串结束符号 $
First()的求法:
例子:
Follow()的求法:
例子:
如何构造预测表呢?
解释一下到底什么是LL(1)?
对于任意的生成式
-
和不相交
- 如果
在中,那么和是不相交的集合。如果在中类似。
LR语法:目前最流行的自底向上语法分析器都基于所谓的LR(k)的语法分析的概念。
如何建立SLR的表呢?
这里想说一下LL预测分析表和SLR语法分析表的区别:
- LL分析表是按照当前的非终结符号和输入符号来确定转换
- SLR是根据当前栈顶和输入符号来确定是移入符号还是规约。