1.1.1 Epsilon闭包计算
同样使用文法
S’ - > S
S – > ( S ) S
S - >
4.2.1节给出了8个项目状态,构成的NFA也有8个状态。如下图:
图表 46
通过NFA的eposilon转换,我们可以得到该文法的DFA。如下图:
图表 47
我们可以看到,在NFA向DFA进行eposilon转换的过程中,DFA中的状态实际上是将NFA的状态中的项作eposilon闭包后合并入同一状态中得到的。因此产生epsilon闭包的项称为核心项(Kernel Item),而被产生的就是闭包项(closure Item),而且闭包项还可以产生新的闭包项。如S’ - > •S是状态0的核心项,S->•(S)S 和S->• 就是闭包项。依据这个特点,实际上生成DFA可以直接从文法中生成,而不必先构造NFA而后在构造DFA,YACC是这样做的,WACC也是这样做的。
在WACC的代码中,见4.2.1节CItem定义的15行给出的函数void ComputerEClosure(CLanguage &L, vector<CItem> &Ivec),该函数就是计算Item的闭包项。下面给出一个测试函数,这个测试函数中的Item项是根据4.2.1节(1)所示的方法手工构造出来的。后面的章节会介绍如何自动生产Item哦。计算文法
A1->A
A->( A )
A->a
的闭包项。
void test4()
{
CLanguage lang;
//定义一个符号集合V
CSymbol A1(1,"A1");//v1
CSymbol A(2, "A"); //v2
CSymbol LP(3,"("); //v3
CSymbol RP(4,")");//v4
CSymbol a (5,"a");//v5
//一.获得CLanguage之vector<CSymbol>
lang.InsertSymbol(A1); //1
lang.InsertSymbol(A);
lang.InsertSymbol(LP); //3
lang.InsertSymbol(RP); //4
lang.InsertSymbol(a); //5
showsym(lang.symbol); //显示之
//二.获得CLanguage之vector<Rules>
//1.获得rightpart之Vector<CSymbol*>
#define vlang(x) (&lang.symbol[x])
//rule1
vector<CSymbol*> rpart1;
rpart1.push_back(vlang( 2 ));
//2。获得leftpart--取得rules
CR