最近对数据结构的研究又有了进展,挺好玩的,总结这些内容的同时,希望也能帮助到大家,这样的话,达到双赢,这才是写博客的目的,接下来我们来轻松学习编译原理,不要被这些纸老虎吓着了。我们一步步来看到底是怎么个情况,该怎么学习呢。。。
其实这部分内容在我上课的时候,是特别头疼的,不知道老师讲的什么,但是经过自己分析琢磨,感觉还好,能分析的差不多,所以就跟大家分享一下:
文法:
我们学习文法主要是认识到这几个方面:
终结符和非终结符:
其实这个特别简单,我们来看个例子就懂了:
S->Ap
S->Bq
A->a
A->cA
B->b
B->dB
这其中我们看到的,S为开始符,S,A,B为非终结符,在左边,可以推导出一个式子来。而p,q,a,b,c,d为终结符。其实咱们一点都不用记,应该太简单了,你这样想,S(start)也是一个非终结符,然后大写的为非终结符,小写的为终结符,那么这个概念就一点难度都没有了
。
文法的类型:
主要是要求咱们判断这几个文法的类型。
0型文法:
0型文法是这几个文法中,限制最少的一个,所以见到的至少是0型文法。G=(Vn,Vt,P,S),其中我们得知道,Vn是非终结符的集合,Vt是终结符的集合,P是推导式的一个集合,S是开始符。我们从图来慢慢分析:
我们从图中来阐述一下这些概念,S,A,B为Vn,而p,q,a,b,c,d,为Vt,S为开始符。整个集合为P。
我们每个式子里边的左边必须要包含这些元素或者元素组合中的至少一个非终结符,右边可以是这些元素的任意组合。我想这样可能好理解一些,这样我们什么公式都不需要记住了,左边有非终结符,右边有终结符,就OK。如:
A->ab。
1型文法:
也叫上下文有关文法;这个1型文法理解起来也没有多大的难度;在0型文法的基础上,我们再添加一点点的限制就行了,我们看添加了什么限制:
右边的长度>=左边的长度,这个长度咱们可以这么来理解,就是这些字符的数量,小的推出大的或者相等的。这样就没有难度了。比如:
A->B,A->Bba 都符合要求,那么反过来,Bba->A就不符合要求了,因为左边是3,右边是1。看图:
2型文法:
叫上下文无关文法。2型文法在1型文法的基础上,我们规定2型文法中,左边必须是非终结符,然而一个终结符一个非终结符的组合不是一个非终结符,如Ab不是一个非终结符,但是两个非终结符的组合就是一个非终结符了,如AB就是行了。
那么应该是这样的:
aB->abc就不符合要求,但是AB->abc就符合要求了。
3型文法:
也叫正规文法,对应有限状态自动机。在2型文法的基础上再加限制。要求更加高。
要么一个非终结符推出一个终结符,要么一个非终结符推出一个终结符并且带一个非终结符。同时说这是一个文法当中的。那么这种属于3型文法,
这右线性与左线性是相互独立的,我们来看例子。
你不能一会写一下右线性一会写一下左线性,这样拼凑在一起就构成不了3型文法了。要写就只写右线性,或者只写左线性,不能一块来,分开来就对了。
那么这几个文法的关系应该是:
接下来我们来实战一下,锻炼一下我们的基础。
我们来做一个题目:
实战:
1、我们分开来写,应该是:A->e A->aB B->Ab B->a
2、我们先来判断是否符合0型文法:0型文法规定左边必须有非终结符,那么这些都是符合的。
3、我们再来看是否符合1型文法:1型文法规定从小推到大。也符合。
4、我们再来看是否符合2型文法:2型文法规定左边必须是非终结符,也满足。
5、我们继续看是否符合3型文法:规定只能符合右线性或者左线性,那么前面一个应该是符合右线性的,后面一个是符合左线性的。所以综合起来就不符合3型文法了。
得出结论:那么这个题目属于2型文法。
正规式:
正规式与正规文法之间的转换:
我们要掌握的三个规则,咱们看一张表就能明确了:
![](https://img-my.csdn.net/uploads/201204/06/1333711868_7821.jpg)
我们来分析一下这些规则;
规则1:文法产生式(A—>xB,B->y ),正规式(A=xy)。对于这个文法产生式转换成正规式,我觉得就是一个代入的过程,把B=y代入A->xB即可得出正规式。反过来,正规式转换成文法产生式,则添加一个变量就搞定了。
规则2:这个式子里边有一个递归,A—>xA,这样就产生递归了,应该是这样的:A->xA,A->xA……这样的无穷下去,最终A还是要等于y的,所以x就有无穷多个,从0个到无穷多个,所以这个推导出来的正规式就是A=x*y,表明x有无穷多个。
规则3:A—>x,A->y。那么A=x|y。这个就很简单了。A退出x或者y。
我们接下来来看看有限自动机:
NFA与DFA的定义:
DFA:确定的有限自动机
M=(S,E,f,So,Z),我们来分析分析这个五元组:
S是一个有限状态集合;
E就是一个输入字符;
f是一个SxE至S的映射;
So:初态;
Z:终态。
我们来看看具体的例子,光是理论和概念的东西最不好理解,来看看例子吧:
DFA=({S,A,B,C,f},{1,0},F,S,{f}),
我们对照上面式子就能看的出来各个元素代表的意义,我们再来分析一遍:
{S,A,B,C,f}是一个状态集合;{1,0}是输入字符;F是一个映射,S是初态,{f}是一个终态。
那么我们接下来看这些映射:
K(S,0)=B,K(S,1)=A,K(A,0)=f,K(A,1)=C,K(B,0)=C,K(B,1)=f,k(C,1)=f;
我们根据这个流程,就有了这么一张图:
![](https://img-my.csdn.net/uploads/201204/09/1333902149_7639.jpg)
然后再看看NFA的定义:
M=(S,E,f,So,Z) 这个五元组跟DFA的定义一样。
编译原理还有这两个的转换,我们在后面的博客中慢慢完善吧~
编译原理这部分咱们先讲这么多,如讲的有不对的地方,还请您指出,将感激不尽~