编译原理——文法规则知识点汇总

文法的定义:G = (Vn, Vt, P, S)

Vn非终结符集合;Vt:终结符集合;P:产生式集合;S:开始符号

则文法就可简单理解为:由开始符号S,根据非终结符Vn和终结符Vt,通过一系列的产生式集合P,来获取想要的结果。

举个简单的文法例子:

S->Aa

A->b

则这个文法就是,G=(Vn={S,A},Vt={a,b},P={S->Aa;A->b},S={S})。

文法的化简:

在构造文法的时候,难免会产生一些不必要的文法规则。所以,我们要对文法进行化简,删除一些不必要的、多余的、有害的规则。

举个文法规则例子:

S->aS | W | U

U->a

V->bV | ac

W->aW

G =(Vn={S,U,V,W},Vt={a,b,c },P={S->aS | W | U;U->a;V->bV | ac;W->aW},S={S})

如何化简:消除无用符号和无用产生式

1、对于G=(Vn,Vt,P,S)(假定L(G)≠Φ),对于每个X∈Vn , 都有w∈Vt*,满足X->w。

2、文法G=(Vn,Vt,P,S)(假定L(G)≠Φ),对于任一x∈Vt′,都存在α、β∈Vn* ,有S-> αxβ。

这么一看,好像云里雾里。别急,首先,我们得明白我们的任务是什么:消除无用符号和无用产生式(说人话,就是消除不能终止的非终结符和不能到达的终结符

任务一:消除不能终结的非终结符

从以上文法规则中,用观察法可以得出,W不能终止,则文法就化简为

G1 =(Vn={S,U,V},Vt={a,b,c },P={S->aS | U;U->a;V->bV | ac},S={S})。(删除不能终止的非终结符号后,同时要把含有该非终结符的路径以及规则都删掉)

任务二:消除不能到达的终结符

由G1文法推导中,开始符号S只能到达a,则删除所有含有b和c的路径,并且,当有推导式中的路径为零时,也要把该推导式删掉,则化简后的文法为

G2 =(Vn={S,U},Vt={a},P={S->aS|U;U->a},S={S})。

消除左公共因子:

首先,我们得明白为什么要消除左公共因子,当我们遇到S->ab|ac,并且我们的目标结果是ac时,计算机不知道应该选择哪条路径去获取ac,它只能一条条路径去遍历,这就降低了效率。如果我们提取了左公共因子a,则S就不需要去做选择,直接选择确定并且正确的路径,就不需要遍历回溯,从而提高了程序效率。

举个例子:

S->aA|a,消除左公共因子后:S->aS',S'->A|Ɛ(Ɛ表示为空)。(跟数学中提取公因子差不多)

by the way,写程序的时候消除左公共因子,可以用树来存储

消除左递归:

还是一样的问题,我们为什么要消除左递归,当我们遇到S->Sa|b时,就会陷入无限循环,

S->Saa|ba|b,我们可以得到,这其实是一个以b开头的一系列个a串,即b或者ba……。

消除直接左递归:

以上例子是直接左递归,消除直接左递归的算法:把终结符放在前面,重新创建一个规则,把左递归变成右递归。如下,S->bS',S'->aS'|Ɛ(Ɛ表示为空)。

消除间接左递归:

例子:

S->Aa

A->Sb|a

这么一看确实没有左递归,但是把S->Aa代入,则变成A->Aab|a,这就又转化为直接左递归,然后执行直接左递归的算法即可。

简单来说,就是从第一条文法规则进行遍历,依次消除各个文法规则的左递归,再把上面已经消除完左递归的、干净的文法规则代入下面的非终结符里面,再进行判断消除。

求各非终结符号的first集合与follow集合:

first集合是选择该非终结符能获取到的第一个终结符。作用:为了避免产生回溯,可直接得出该非终结符号的第一个终结符是什么,可以直接选择匹配。

算法:

follow集合是该非终结符接下来第一个能到达的终结符。作用:为了判断是否应该选择Ɛ,根据它的下一个终结符是啥,如果匹配,则选择Ɛ,如果不匹配,可直接报错退出。

算法:

判断是否是线性规则:

左线性:形如A->Ba或A->a

右线性:形如A->aB或A->a

推导结果要么是终结符,要么是非终结符加终结符,而且所有规则全部都要为左线性或者全部都要为右线性,不能乎左乎右,不然就是非线性。

如果判断该文法是线性文法,则转化为正则表达式,进而求出NFA、DFA以及DFA的最小化。

线性文法转正则表达式:

举个例子:

S->aA

A->bB

B->a

则S->aA=>S->abB=>S->aba,所以该文法规则的正则表达式是aba。

正则表达式转NFA、DFA以及DFA的最小化:

(55条消息) 编译原理——正则表达式->NFA->DFA_Wu_L7的博客-CSDN博客_正则表达式到nfa到dfa的例题

  • 17
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值