编译原理——判断文法是否为算符优先文法

编译原理——判断文法是否为算符优先文法

在判断之前我们需要看一下该文法是否为算符文法。

算符文法定义

一个文法,如果它的任意产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部:
…QR…
那么我们称该文法为算符文法。


接下来就可以构造优先关系表了,再构造之前我们需要了解两个基本知识。

1.算符优先关系

关系有三种:
a a>b a的优先性高于b
a=b a的优先性等于b
注意:<,>,=写的时候中间有个点,而且关系不像数学中的那样,aa,a=b也不一定意味着b等于a。

2.FIRSTVT集和LASTVT集的构造方法

FIRSTVT集构造方法:
1.P->a…或者P->Qa…,那么a∈FIRSTVT(P)
2.a∈FIRSTVT(Q)且P->Q…,那么a∈FIRSTVT(P)

LASTVT集构造方法:
1.P->…a或者P->…aQ,那么a∈LASTVT(P)
2.a∈LASTVT(Q),P->…Q,那么a∈LASTVT(P)

看上去是不是很简单,那我们
编译原理——判断文法是否为算符优先文法_第1张图片
设有文法G:
S→a|b|(A)
A→SdA|S

对于FIRSTVT(S),很容易看出来有a,b(…在这里就是空字),还有(【这里的…就是A)】,对于FIRSTVT(A),有d(应用了P->Qa…),再通过第二条规则,在这里SdA和S哪个产生式都行,可以看出要把FISRTVT(S)加到FIRSTVT(A)里,所以我们得到:
FIRSTVT(S)={a,b,( };
FIRSTVT(A)={a,b,d,( };
注意:FIRSTVT(S)和FIRSTVT(A)写的顺序不可以调换,看文法的顺序,S在上就先写S的,一会要用到。


对于LASTVT(S),有a,b,)【这里用的是P->…Qa,还有印象吧】,对于LASTVT(A),有d,根据A->…Q,(这里的…就是空字),我们可以看出还要把LASTVT(S)加到LASTVT(A)里,所以我们得到:
LASTVT(S)={a,b,)};
LASTVT(A)={a,b,d,)};

构造优先关系表

编译原理——判断文法是否为算符优先文法_第2张图片
这是针对上述文法的优先表,我们来说一下怎么构造。
我们先找填写=的,若文法中产生式有满足P->…ab…或P->…aQb…的那么就直接填写=,注意顺序是左边等于右边,对应表是横着的等于竖着的,这里是(=),#号直接填写等于就好了。
然后再去文法中找类似于P->QaR这种有用的文法,终结符和非终结符在一起的那种。找到后根据以下两条:
1.a小于FIRSTVT(R)中元素,横着写
2.LASTVT(Q)中元素大于a,竖着写

比如这里A->SdA,d小于FIRSTVT(A),对应着倒数第二行a,b,(,d那里都填了<,然后LASTVT(S)都大于d,对应着倒数第二列a,b,)那里都填了>。
剩下的大家可以自己对照着看。
最后是#号的填法,用到了第一个FIRSTVT集和LASTVT集(所以才说不可以调顺序),填法跟上面的一样,横着的都小于FIRSTVT集,像这里最后一行#小于a,b,(,然后LASTVT集元素大于#,竖着的填>,像这里对应最后一列,a,b,)那里都填了>。

表构建完了我们就可以写结论了:
该文法任一产生式右部都不含两个相继的非终结符,故为算符文法。从上表可以看出,任何两个终结符之间至多满足=,<,>,三种关系之一,故该文法为算符优先文法。


个人觉得编译原理算是比较难的了,我也是第一次写博客,想通过大白话让大家都能看懂,错误的地方还望各位大牛指正,提提宝贵意见。
编译原理——判断文法是否为算符优先文法_第3张图片

你可能感兴趣的:(编译原理)