
1 . 上下文无关语法 设计要求 : 设计一个语法 , 使用该语法生成语言
, 该
语言的字符串的开始和结尾的字符是相同的 ;
2 . 设计方法 : 非确定性优先自动机 ( NFA ) 识别某语言 , 将 NFA 转为 确定性优先自动机 ( DFA ) , 然后将 DFA 转为 上下文无关语法 ;
3 . 语法设计要求分析 :
, 要么就是
;
, 对应的结尾字符也是
;
, 对应的结尾字符也是
;
4 . 初始状态
规则 : 上述语法描述转为规则 如下 , 其中
为初始状态 ;
5 .
规则 :
表示中间的字符串 , 这个
字符串可以是任意字符串 , 根据下面的规则可以生成任意的
组成的字符串 ;
给出如下上下文无关语法 ( CFG ) :
语法的含义是 :
可以被
替换 ;
可以被
替换 ;
可以被
替换 ;
可以被
替换 ;
1 . 语法的有歧义性 : 同样的一个字符串 , 可以有不同的语法分析树 ;
① 语法分析树 1 :

2 . 在上述的 语法分析树中 , 加法优先级高于乘法 , 这是错误的分析 ;
② 语法分析树 2 :

在上述的 语法分析树中 , 乘法优先级高于加法 , 这是正确的分析 ;
3 . 语法歧义性分析 : 上述语法中是无法区分 加法 和 乘法的优先级的 , 因此这里得到两个完全不一致得我语法分析树 , 那么该语法是有歧义的 ;
4 . 与代数表达式语法对比 : 之前讲的代数表达式是好的语法 , 乘法 和 加法的优先级 也体现出来 , 乘法优先级高于加法 , 括号的优先级高于乘法 ;
① 代数表达式语法 :
② 代数表达式语法分析树 : 这个语法分析树是唯一的 , 没有其它的形式 , 该语法是没有歧义的 ;

③ 有歧义的语法 : 在本节的语法中 , 无法区分 加法 和 乘法的优先级 , 该语法是有歧义的 ;
5 . 总结 : 如果语法有歧义 , 那么中间的字符串有歧义 ; 没有算法 可以判定 上下文无关语法 是否有歧义 ; 有些语法天生就是有歧义的 , 但可以通过某种方法去掉语法中的歧义性 ;
1 . Chomsky 范式 : 上下文无关语法中的任何规则都是如下格式 ;
①
:
是 变元 ,
也是变元 ;
②
:
是 变元 ,
是常元 ,
可以被终端字符替换 ;
③
变元要求 :
变元一定不能是开始变元 ;
④
:
开始变元可以为空 ;
⑤ 不能出现
单个变元 到 单个变元不允许出现 ;
2 .
规则 说明 :
① 语言包含空字符串 : 如果上下文无关语法包含空字符串时 , 一定需要
规则 ;
② 语言不包含空字符串 : 如果上下文无关语法不包含空字符串时 , 一定不需要
规则 ;
③ 规则总结 : 该规则决定 上下文无关语法 所生成的语言 是否包含 空字符串 , 如果包含必须要这个规则 , 如果不包含空字符串一定不要这个规则 ;
Chomsky 范式规则 的 上下文无关语法 生成的语言 的语法分析树 除叶子节点之外 都 是二叉树 , 叶子节点 与 上一层都是 一对一的节点 ;
任何 上下文无关语法 , 都可以找到一个 Chomsky 范式 与其等价 ;
任何 上下文无关语法 的语法分析树 都可以进行修剪 , 修剪后的树都是二叉树 ;
上下文无关语法 转为 Chomsky 范式 步骤 :
1 . 添加开始变元及规则 : 添加一个新的开始变元
, 以及配套的规则
,
是旧的开始变元 ;
① 目的 : 添加开始变元的目的是 开始变元 永远出现在左边 ;
② Chomsky 范式 中 , 开始变元始终在规则的左边 , 不允许开始变元在规则的右侧 ;
③ 对应 Chomsky 范式 规则 :
规则 ,
是 变元 ,
也是变元 , 并且
不允许是开始变元 ;
2 . 消除所有的
规则 : 消除所有从 变元 到 空字符 的规则 ;
3 . 消除所有的
规则 : 消除所有从 单个变元 到 单个变元的 单条规则 , 允许从 单个变元 到 多个变元或常元 ;
如
是需要删除的 ,
可以保留 ;
将 上下文无关语法
转为 Chomsky 范式 :
转换过程如下 :
1 . 添加新的开始变元 :
, 旧的开始变元
就不是开始变元了 ;
当前的语法格式如下 :
2 . 消除
规则 :
消除
规则 原则 : 假设有规则
,
, 如果要删除
规则 , 需要实现 消除前后具有 相同的替换效果 , 将规则改为
即可删除
相关规则 ; ( 消除前后 , 替换效果必须一致 )
3 . 消除
中的
: 会影响
和
两条规则中涉及到了
变元 , 消除的原则是 " 消除前后 , 替换效果必须一致 " ;
3.1 .
规则消除
分析 : 这里讨论 消除
规则中的
规则 对
的影响 ;
① 消除
规则前分析 : 使用
规则 对
进行替换 有两种情况 , 分别是
,
, 两种情况 ;
② 消除
规则后分析 : 如果要消除
规则 , 那么消除后的规则是
, 使用
规则对
进行替换 , 其替换 结果必须是
,
, 两种情况 ;
分析
,
两种结果 :
使用
规则替换 , 可以得到
;
替换结果无法获取 , 此时需要在
的平级 , 再次添加
即可达到上述效果 ;
最终修改方案 : 将
改为
, 使用
规则替换
的结果是
,
, 与上述消除
规则 前的结果一致 ;
③
规则对应的消除
规则后的结果为
④ 当前的语法格式如下 : 注意 还没有讨论
规则中的
,
规则中的
还不能删除 ;
: 注意此时该规则不完善 , 还没有删除
;
3.2 .
规则消除
分析 : 这里讨论 消除
规则中的
规则 对
的影响 ;
① 消除
规则前分析 : 使用
规则 对
进行替换 有两种情况 , 分别是
,
, 两种情况 ;
② 消除
规则后分析 : 如果要消除
规则 , 那么消除后的规则是
, 使用
规则对
进行替换 , 其替换 结果必须是
,
, 两种情况 ;
分析
,
两种结果 :
使用
规则替换 , 可以得到
;
替换结果无法获取 , 此时需要在
的平级 , 再次添加
即可达到上述效果 ;
最终修改方案 : 将
改为
, 使用
规则替换
的结果是
,
, 与上述消除
规则 前的结果一致 ;
③
规则对应的消除
规则后的结果为
④ 当前的语法格式如下 : 注意 还没有讨论
规则中的
,
规则中的
还不能删除 ;
4 . 消除
中的
: 会影响
规则中涉及到了
变元 , 消除的原则是 " 消除前后 , 替换效果必须一致 " ;
① 消除
中的
, 添加以下项即可 :
通过
代替 : 添加
项 ;
通过
代替 : 添加
项 ;
都通过
代替 : 是
, 可以不同写 ,
没啥意义 ;
②
规则对应的消除
规则后的结果为 :
③ 当前的语法格式如下 :
5 . 消除
规则 :
假设要消除
规则 : 如果语法中有
规则 , 那么如果消除
, 需要将
体现出来 ;
消除
规则 , 检查
出现在规则左边的情况 , 这里有
规则 , 需要 添加
规则后 , 即可删除
规则 ;
删除前规则 :
删除后规则如下 :
6 . 消除
规则 :
① 消除
规则 , 检查
出现在规则左边的情况 , 这里有
规则 , 需要 添加
规则后 , 即可删除
规则 ;
② 删除前规则 :
③ 删除后规则如下 :
7 . 分解规则 :
① 分解示例 :
可以分解为
,
② 分解前的规则 :
③ 分解后的规则 :
下面的规则 是
分解后的规则 :
下面的规则 是
分解后的规则 :