实验报告实验一编写词法分析程序Word文档格式.docx
《实验报告实验一编写词法分析程序Word文档格式.docx》由会员分享,可在线阅读,更多相关《实验报告实验一编写词法分析程序Word文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
![实验报告实验一编写词法分析程序Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-10/20/b03ab702-0d0d-4776-b582-6817653e2be8/b03ab702-0d0d-4776-b582-6817653e2be81.gif)
2)保留字:
标符的子集,包括:
if,else,for, while,do,int,write,read。
正则表达式:
if|else| for |while|do|int|write |read
3)无符号整数:
由数字组成,但最高位不能为0,允许一位的0。
( (1……|9)(0|1|……|9)* )|0
4)分界符:
(、)、;
、{、}
(|)|;
|{|}
5)运算符:
+、-、*、/、=、<
、>
、>=、<
=、!
=、==
+|-|*| /|= |< |>
|>=|<
=| !
= |==
6)注释符:
/* */
/*(没有连续的*/的任意字符串|ℇ)*/
2、对每个文法或者正则表达式分别构造NFA
(a|b|……|z|A|B……|Z )(0|1|……|9|a|b|……|z|A|B……|Z)*
2)无符号整数:
((1|2|……|9)( 0|1|……|9)*)|0
3)分界符:
(| )|;
|{|}
4)运算符:
+|-| * | /|=|<
| >
|>
=|<
= |!
=|==
5)注释符:
/*(没有连续的*/的任意字符串|ℇ)*/
3、将NFA合并,确定化,化简得到最终的DFA。
NFA:
DFA:
三、实验过程
1、完成整个实验的先后步骤
a)根据TEST语言的词法规则,分别写出每条规则的正则文法或者正则表达式;
b)将每一个正则文法或者正则表达式转换为NFA;
c)将多个NFA合并后进行确定化并化简;
d)根据化简后的DFA画出流程图;
e)参阅教材PP.69-71的TEST语言语法规则,确定单词分类、单词输出方案;
f)编写词法分析程序;
g)对下面的TEST语言源程序进行词法分析,将合法单词存入lex.txt,并报告词法错误及其位置。
注:
不能修改源程序
{
/*Thisatestprogram.*/
intabc;
int123;
int A$@;
inti;
intn;
int b,c;
int2a;
inta2;
readn;
n =012345;
for (i=1;
i<
=n;
i=i+1)
{
abc=abc+i;
}
if(i!
=n)n=n+i;
if(!
n)b =b+c;
/*Theloopended
writeabc;
2、实验调试记录(问题表现,分析原因,解决方案,解决结果)
a)问题表现:
1.不能处理除号
2.不能处理不完整的注释符
3.对于”0123”这类字符串的处理不正确,我之前处理为直接报错说一位以上的数字首位不能为0
b)分析原因:
问题1,2的原因都是在“/”符号处理时出现的问题导致的,程序中出现bug使得一遇到‘/’就会进入死循环。
问题3 ,不应该直接报错说一位以上的数字首位不能为0,遇到0应该直接输出0这个单词,再接着读数字。
c)解决方案:
d)对于问题1,2,重新梳理逻辑,一步一步对照流程图和DFA来调试修改代码。
对于问题3,遇到0应该直接输出0这个单词,再接着读数字。
e)解决结果:
成功解决了程序遇到‘/’进入死循环问题和“0123”这类字符串的处理。
三、实验结果
列出实验结果并进行分析(含分步测试结果)。
lex.txt文件(存放编译的合法内容)内容:
1ﻩ{ﻩ{
2/*Thisatestprogram.*/ﻩ/*Thisatest program.*/
3ﻩintint
3IDﻩabc
3ﻩ;
ﻩ;
4ﻩintint
4NUMﻩ123
4;
ﻩ;
5ﻩintint
5ﻩIDA
5ﻩ;
6ﻩintﻩint
6IDi
6ﻩ;
7ﻩintint
7IDﻩn
7;
;
8ﻩintﻩint
8IDb
8ﻩIDc
8;
;
9intint
9ﻩNUM2
9ﻩIDa
9;
10ﻩintint
10ﻩIDﻩa2
10;
11readﻩread
11IDﻩn
11ﻩ;
12IDﻩn
12=ﻩ=
12ﻩNUMﻩ0
12NUM12345
12ﻩ;
13forfor
13ﻩ((
13IDi
13ﻩ==
13NUMﻩ1
13ﻩ;
13ﻩIDi
13ﻩ<=ﻩ<
=
13IDn
13;
13IDﻩi
13IDi
13ﻩ+ﻩ+
13ﻩNUMﻩ1
13ﻩ))
14ﻩ{ﻩ{
15IDﻩabc
15ﻩ==
15ﻩIDﻩabc
15++
15IDi
15;
16}}
17ifif
17ﻩ((
17IDﻩi
17!
=ﻩ!
17ﻩIDﻩn
17)ﻩ)
17IDn
17==
17ﻩIDn
17++
17ﻩIDi
17;
18ifﻩif
18ﻩ((
18ﻩIDﻩn
18ﻩ))
18ﻩIDb
18ﻩ=ﻩ=
18IDb
18++
18IDc
18;
四、讨论与分析
1.你的编写词法分析程序满足最长匹配原则吗?
如果满足请给出你的实现方案。
如果不满足请给出改进方案。
答:
不满足,我的处理先后顺序是:
标识符或保留字、数字、分界符、运算符(除开/)、除或者注释,我应该吧注释放在前面,因为一般来说注释都比其它类型符号长些。
改进措施便是将注释这一条词法规则最早处理。
2.给出你的单词分类方案,并说明理由。
根据TEST语言可将单词分为六类:
a)标识符:
字母打头,后接任意字母或数字。
b)保留字:
标识符的子集,包括:
if,else,for, while,do,int,write, read。
c)无符号整数:
由数字组成,但最高位不能为0,允许一位的0。
d)分界符:
、{、}
e)运算符:
+、-、*、/、=、<、>、>=、<
=、!
f)注释符:
/* */
3.构建词法分析程序一般过程是怎样的?
构建词法分析程序的一般过程:
1、根据词法规则写出正则文法或者正则文法。
2、为每一个正则表达式构造一个NFA,然后将多个NFA合并为一个NFA
3、将NFA转化成DFA,并且化简最小化DFA
4、确定单词的输出形式
5、根据化简后的DFA和单词输出程序构造词法分析程序
(主要部分:
通过实验对课程知识点的理解;
回答实验指导书的实验思考提出的问题等)
五、附录:
关键代码(给出适当注释,可读性高)
#include<iostream>
#include<
fstream>
# include<
stdio.h>
# include<stdlib.h>
#include <
string>
usingnamespace std;
constintKWN=8;
//关键字的个数
constintMAXSIZE=400;
//标识符最长个数
charkword[KWN][10]= { //关键字
ﻩ"if",
ﻩ"else"
ﻩﻩ"for"
,
ﻩﻩ"
while"
ﻩ"
do"
int"
ﻩ"read"
"
write"
};
intline =1;
//行号
interrors =0;
ﻩﻩﻩﻩﻩ//记录错误个数
ofstream fout;
//输出文件流
ifstreamfin;
ﻩﻩﻩﻩ//输入文件流
ofstreamlexout;
ﻩﻩﻩ //存放合法单词的文件流
chartype[6][30]={
ID"
ﻩ"
保 留 字",
ﻩ"
NUM"
分界符"
ﻩﻩ"运 算符"
ﻩ"
注释 符"
ﻩintmain()
{
ﻩﻩintTEST();
ﻩﻩﻩﻩ//函数声明
ﻩTEST();
ﻩﻩﻩif(errors==0)
ﻩ{
cout<<
"
编译成功。
<
<endl;
ﻩﻩ}
ﻩﻩﻩelse
ﻩ{
ﻩcout<
<"
编译失败。
共发现"<
errors<
"个错误!
"<
<endl;
ﻩ}
ﻩreturn0;
ﻩ}
ﻩ
ﻩﻩ////判断是否为字母
ﻩint is_Char(char ch)
ﻩ{
ﻩif((ch>
='a'
&
ch<
='
z')||(ch>
='A'&
='Z'))
ﻩreturn 1;
ﻩreturn 0;
}
ﻩ
ﻩﻩ////判断是否为无符号整数
intis_Uint(charch)ﻩﻩﻩ
ﻩﻩ{
ﻩﻩif('0'
=ch&
ch<
='9'
)
ﻩﻩﻩ{
ﻩreturn1;
ﻩ}
ﻩreturn 0;
ﻩﻩ}
ﻩ////判断是否为分界符
int is_Deli(charch)ﻩﻩ
ﻩ{
ﻩif(ch=='('
||ch=='
)'||ch==';
'||ch=='
{'||ch=='
}'
ﻩﻩreturn1;
ﻩreturn0;
}
ﻩ////判断是否为操作符
ﻩintis_Oper(char ch)ﻩﻩﻩ
{
ﻩcharOperater[10]="
+-*!
=><"
;
//没有考虑/号
ﻩﻩfor(inti=0;
i<8;
i+