词法分析器实验报告Word文档格式.docx

上传人:b****5 文档编号:20543282 上传时间:2023-01-23 格式:DOCX 页数:12 大小:393.02KB
下载 相关 举报
词法分析器实验报告Word文档格式.docx_第1页
第1页 / 共12页
词法分析器实验报告Word文档格式.docx_第2页
第2页 / 共12页
词法分析器实验报告Word文档格式.docx_第3页
第3页 / 共12页
词法分析器实验报告Word文档格式.docx_第4页
第4页 / 共12页
词法分析器实验报告Word文档格式.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

词法分析器实验报告Word文档格式.docx

《词法分析器实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《词法分析器实验报告Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。

词法分析器实验报告Word文档格式.docx

publicclassState{

/*既是其ID号,又是在状态集中的索引*/

privatefinalintID=StateCounter++;

privateclassAdj{/*邻接边*/

charroute;

/*路由字符*/

Statestate;

/*邻接状态*/

publicAdj(charr,Stated){

route=r;

state=d;

}

}

/*邻接边集*/

ArrayList<

Adj>

adjList;

}

/*记录状态数,并为新状态的ID赋值*/

privatestaticintStateCounter=0;

publicArrayList<

Character>

charSet;

/*字符集*/

State>

states;

/*状态集*/

publicStatestartState;

/*开始状态*/

endStates;

/*结束状态集*/

处理正规表达式的方法集

/*正规表达式*/

publicclassRegEx{

/*代表所有数字*/

publicstaticfinalStringDIGIT="

1&

2&

3&

4&

5&

6&

7&

8&

9&

0"

;

publicstaticfinalcharEND='

$'

/*代表表达式的末尾*/

publicstaticfinalcharNULL_CHAR='

~'

/*空字符*/

publicstaticfinalcharTRANSFER='

\\'

/*转义符,暂时未用*/

/*正规式中的运算符,数组的第一个运算符的优先级最高,最后一个优先级最低*/

publicstaticfinalchar[]OPERATORS=

{'

('

'

*'

&

'

|'

)'

'

};

/*判断字符r是否为运算符*/

publicstaticBooleanisOperator(charr)

/*判断字符r是否为可接受的字符*/

publicstaticBooleanisOperand(charr)

/*比较栈中运算符和正规式中运算符的优先级,在构造NFA的后缀求值中使用*/

publicstaticcharcmpPriority(charopInStack,charopInRE)

/*对正规式进行简单的验证,不符合定义时将抛出异常*/

publicstaticvoidcheck(Stringexpr)

NFA数据结构示意图

publicclassNFA{/*不确定状态机*/

privatefinalintID=stateCounter++;

classAdj{

publicAdj(charr,States){

state=s;

privateAdjlNode;

/*左邻接*/

privateAdjrNode;

/*右邻接*/

privatestaticintstateCounter=0;

publicStateendState;

/*结束状态*/

核心算法伪代码:

算法1Thompson算法

输入正规式w

输出一个接受同一正规集的NFA

辅助数据结构

NFA状态对{NFA起始状态;

NFA终止状态}。

存储已构建的NFA的初态和终态

NFA栈:

以NFA状态对作为栈元素。

运算符栈:

以RegEx中定义的正规式的运算的运算符作为栈元素

实现方法:

利用正规式的运算符进行正规式后缀求值

具体如下例:

正规式为(a&

b|b)*。

以$为结束符

(s,f)表示某一NFA从s状态开始,到f结束。

步骤

NFA栈

运算符栈

输入序列

动作

1

$

(a&

b|b)*$

(入栈

2

$(

a&

0-a->

1,(0,1)入栈

3

(0,1)

入栈

4

$(&

2-b->

3,(2,3)入栈

5

(0,1)(2,3)

|b)*$

出栈

(0,1)(2,3)出栈

1-ε->

(0,3)入栈

6

(0,3)

|入栈

7

$(|

b)*$

4-b->

5,(4,5)入栈

8

(0,3)(4,5)

)*$

|出栈

(0,3)(4,5)出栈

6-ε->

0,6-ε->

3-ε->

7,5-ε->

(6,7)入栈

9

(6,7)

(出栈

10

*$

*入栈

11

$*

*出栈

(6,7)出栈

8-ε->

6,8-ε->

7-ε->

6,7-ε->

(8,9)入栈

12

(8,9)

$出栈

13

结束

其中:

算法2求ε_闭包

输入NFA状态集T:

由可变数组存储,每个数组元素为一个状态

输出NFA状态集T的ε_闭包U:

同上

实现方法

forT中的每一个状态s

loopifs未被访问then将s加入到U中endif

while有新状态t加入Udo

if由t经ε转移至左结点tl且tl未被访问过

then将tl加入到U中endif

if由t经ε转移至右结点tr且tr未被访问过

then将tr加入到U中endif

end

endloop

算法3子集法

输入一个NFAN

输出一个接受同一正规集的DFAD。

其中,含有NFA初态的DFA状态为DFA的初态,所有含有NFA终态的DFA状态为DFA的终态

classFAPair{

DFA.StatedfaState;

NFA.State>

nfaStates;

FAPair{DFA状态;

NFA状态集}。

在创建DFA状态时存储DFA状态及其相对应的NFA状态集

FAPair>

FAPair集:

存储创建DFA过程中产生的FAPair

Queue<

FAPair队列:

存储未被访问过的DFA状态

实现方法

构建起始FAPair(s0,ε_闭包({s0}));

将其压入FAPair队列,并收录至FAPair集中;

将s0收录至DFA状态集中,s0为DFA的初态;

while队列不为空

弹出队列的首元素,并取其DFA状态d和NFA状态集T;

ifT中包括NFA的终态thend为DFA的终态;

endif

for每一个输入字符a

loop

U:

=ε_闭包(smove(T,a));

ifU不为空

在FAPair集中查找U所对应的DFA状态d’

if没有相对应的DFA状态d’

then创建DFA状态d’,在d的邻接边集中加入邻接边(a,d’);

构建起始FAPair(d’,U);

将其压入FAPair队列,并收录至FAPair集中

else直接在d的邻接边集中加入邻接边(a,d’)

endif

endloop

DFA的字符集=NFA的字符集;

算法4DFA最小化

输入一个DFAD={S,∑,Dtran,s0,F}

输出一个DFAD’={S’,∑,Dtran’,s0’,F’},它和D接受同样的正规集,但是状态数最少

辅助数据结构:

Integer>

划分:

存储一个划分,每个结点存储DFA状态在DFA中的索引

>

划分表:

存储所有的划分

int[DFA状态数]划分映射表:

存储每个DFA状态所在的划分在划分表中的索引

(1)构造划分表∏,∏[0]=划分{F};

∏[1]=划分{S-F}。

∏[1]可能为空

(2)构造划分映射表M

forDFA中的每个状态d

loopifd∈划分{F}thenM[d]=0

elseM[d]=1

(3)应用下述过程构造新的划分∏new:

∏new=∏;

for∏new的每一个划分G={d1,d2,d3,d4...}

for∑中的每一个字符a

loop

d1’=smove(d1,a);

预构造新划分U;

forj=2,3,4...

loop

dj’=smove(dj,a)

ifd1’和dj’中有一个出错状态

或d1’和dj’中没有出错状态但M[d1’]≠M[dj’]

then将dj从G中去掉并加入到划分U中endif

endloop

if有状态加入划分U中

then将新组U加入∏;

重新执行步骤(3);

endif

endloop

(4)利用∏new构建D’

for∏new中的每一个组Gi

取Gi的第一个状态d;

在D’中构建状态di’;

ford的邻接边集中每个邻接边Adj

在di’的邻接边集中加入

邻接边(Adj.route,D’状态集中的第(M[Adj.state])个状态)

实验结果:

正规式:

acd*|(a)*测试字符串为空接受

ab*(ab|c*a)测试字符串:

aa接受

(a|b)*abb测试字符串:

bb不接受

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1