NFA 确定化为 DFA
1.实验目的
设计并实现将 NFA 确定化为 DFA 的子集构造算法, 从而更好地理解有限自动机之间的 等价性,掌握词法分析器自动产生器的构造技术。该算法也是构造 LR 分析器的基础。
2.实验要求
设计并实现计算状态集合I的£闭包的算法& _Closure(l)和转换函数 Move(l,a),并
在此基础上实现子集构造算法 Subset_Construction 。利用该从 NFA 到 DFA 的转换程序 Subset_Construction,任意输入一个NFA N= (S,工,S ,s0,F ),输出一个接收同一语言的
DFA M=(S',工,S ' ,s0 ' ,F ')。
3.实验内容
(1)令I是NFA N的状态集S的一个子集,I的£闭包的& _Closure(I)构造规则如下:
若 s€ I,贝U s€& _Closure(I);
若 s €& _Closure(I) 且 S (s,& )=s '而 s' ? & _Closure(I) ,贝U s' €&
_Closure(I)
根据上面的规则,下面给出了一个计算 I 的&闭包的算法& _Closure(I) 。
SET S;
SET& _Closure(input)
SET *input;
{
S=input; /*初始化 */
push(); /*把输入状态集中的全部状态压入栈中*/
while( 栈非空 ){
Nfa_state i;
pop(); /* 把栈顶元素弹出并送入 i */
if(存在 S (i,& )=j)
if(j 不在 S 中 ) {
把 i 加到 S 中 ;
把j压入栈中;
}
}
return S; /*返回& _Closure(input)集合 */
}
完成上述算法的设计。
⑵ 令I是NFA N的状态集S的一个子集,a€X ,转换函数 Move(l,a)定义为:
Move(l,a)= & _Closure(J)
其中,J={s '|s € I 且3 (s,a)=s ' }
转换函数Move(I,a)的设计通过调用& _Closure(input) 实现,完成该函数的设计。
(3)从NFA N构造一个与其等价的DFA M的子集构造算法,就是要为DFA M构造状态转
换表Trans ,表中的每个状态是NFA N状态的集合,DFA M将“并行”地模拟 NFA N
面对输入符号串所有可能的移动。下面给出了子集构造算法Subset_Co nstructi on
的框架,请完成其设计过程。
有关数据结构:
States[] 是一个M的数组,每个状态有两个域,set域存放N的状态集合,
flg域为一标识。
Trans[]是M的转移矩阵(输入字母表工元素个数x最大状态数),
Tran s[i][a]=下一状态。
i M的当前状态号
a输入符号,a
Nstates[] M的下一新状态号
S定义M的一个状态的N的状态集
初始化:
States[O].set= & _Closure({N 的初态})
States[O].flg=FALSE
Nstates=1
i=0
S= ①
Trans初始化为无状态'-'
while(States[i] 的 flg 为 FALSE){
States[i].flg=TRUE;
for(每个输入符号a€S ){
S= e _Closure(Move(States[i].set,a));
if(S非空)
if(States中没有set域等于S的状态){
States[Nstates].set=S;
States[Nstates].flg=FALSE;
Tran s[i][a]= Nstates++;
}
else
Trans[i][a]= States中一个 set 域为 S 的下标;
}
}
此算法的输出 M主要由Trans矩阵描述,其中省略了每个状态是否为终态的描述, 加以完善。
4.实验程序;
#in clude
#in clude
#defi ne MAXS 100
using n amespace std;
string NODE; // 结点集合
string CHANGE; //终结符集合
int N; 〃NFA边数
struct edge{
stri ng first;
stri ng cha nge;
stri ng last;
};
struct cha n{
stri ng ltab;
stri ng jihe[MAXS];
};
void kon g(i nt a)
{
int i;
for(i=0;i
cout?'';
}
//排序
void paixu(stri ng