编译原理笔记(三)——DFA的代码表示

DFA的代码表示笔记

DFA是一个有向图

  • 不同的代码表示
    • 转移表
    • 哈希表
    • 跳转表

​ 其构造却决与在实际实现中面对时间空间的权衡

转移表

以正则表达式为例a(b|c)*,其状态转移图为

image-20211114162531479

在C语言中可以用一个二维数组来表示

状态/字符abc
01errorerror
1error11
#define ERROR -1

char table[M][N]; // 大小根据字符集的大小来确定 

// init char table
table[0]['a'] =	1;
table[1]['b'] = 1;
table[1]['c'] = 1;
// other is error state, error = -1
.....

有一个驱动算法,当字符流输入的时候,驱动算法依据符号表输出记号流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WRbhhSh2-1637423307872)(https://i.loli.net/2021/11/14/H5MTA8ZFUl12ckg.png)]

nextToken();  // 字符流提供的一个接口
state = 0;
stack = [];
while(state != ERROR){
 c = getChar();  // 获取一个字符,与本算法无关的一个接口
 if(state is ACCEPT) // ACCEPT是特殊的接受状态,如果接受,之前的输入是不需要考虑的
     clear(stack);
 push(state);
 state = table[state][c];
}

while(state is not ACCEPT)
 state = pop();
	rollback(); // 分析出错,字符指针回退,回退一个字符

转移表有一个很大的缺点,就是占空间,几个状态就要占据很大的一个空间,某些时候如果对空间性能要求特别严格的话,可能使用这一个方法不是最佳的一种选择。而跳转表法则解决了这一个占空间的问题,局部性非常突出,很多解决方案也会考虑采用这种解决方法

最长匹配原则

"ifif"这样的类型,他会匹配,ifif,而不会只匹配if

跳转表(go to table或者jump table)

还是上面的例子,用跳转表写的话,可能是这样的

nextToken();
state = 0;
stack = [];
goto q0;

q0:
	c = getChar();
	if(state is ACCEPT)
        clear(stack);
	push(state);
	if(c == 'a')
        state = 1;
        goto q1;
	state = ERROR;
	goto error_code;

q1:
	c = getChar();
	if(state = ACCEPT)
        clear(stack);
	push(state);
	if(c == 'b' || c == 'c')
        state = 1;
        goto q1;
	state = ERROR;
	goto error_code;

error_code:
	while(stats is not ACCEPT)
        state = pop();
        rollback();

......
1. 实验内容 每一个正规集都可以由一个状态数最少的DFA所识别,这个DFA是唯一的(不考虑同构的情况)。任意给定的一个DFA,根据以下算法设计一个C程序,将该DFA 化简为与之等价的最简DFA。 2. 实验设计分析 2.1 实验设计思路 根据实验指导书和书本上的相关知识,实现算法。 2.2 实验算法 (1)构造具有两个组的状态集合的初始划分I:接受状态组 F 和非接受状态组 Non-F。 (2)对I采用下面所述的过程来构造新的划分I-new. For I 中每个组G do Begin 当且仅当对任意输入符号a,状态s和读入a后转换到I的同一组中; /*最坏情况下,一个状态就可能成为一个组*/ 用所有新形成的小组集代替I-new中的G; end (3)如果I-new=I,令I-final=I,再执行第(4)步,否则令I=I=new,重复步骤(2)。 (4)在划分I-final的每个状态组中选一个状态作为该组的代表。这些代表构成了化简后的DFA M'状态。令s是一个代表状态,而且假设:在DFA M中,输入为a时有从s到t转换。令t所在组的代表是r,那么在M’中有一个从s到r的转换,标记为a。令包含s0的状态组的代表是M’的开始状态,并令M’的接受状态是那些属于F的状态所在组的代表。注意,I-final的每个组或者仅含F中的状态,或者不含F中的状态。 (5)如果M’含有死状态(即一个对所有输入符号都有刀自身的转换的非接受状态d),则从M’中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。 。。。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值