实验一词法分析.docx
- 文档编号:9671597
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:15
- 大小:312.90KB
实验一词法分析.docx
《实验一词法分析.docx》由会员分享,可在线阅读,更多相关《实验一词法分析.docx(15页珍藏版)》请在冰豆网上搜索。
实验一词法分析
实验一词法分析
1、实验目的
通过设计、编写和调试词法分析程序,了解词法分析程序的作用,组成结构,不同种类单词的识别方法,掌握由单词的词法规则出发,画出识别单词的状态转换图,然后在用程序实现词法分析程序设计方法。
2、词法规则
1、注释用{和}括起来。
注释体中不能有{。
注释可以出现在任何记号的后面。
2、记号间的空格可有可无,但关键字前后必须有空格、换行、程序的开头或者结尾的原点。
3、标识符的记号id与以字母开头的字母数字串相匹配:
Letter->[a-zA-Z]
Digit->[0-9]
Id->letter(letter|digit)*
4、记号num与无符号整数相匹配:
Digits->digitdigit*
Optional_fraction->.Digits|ɛ
Optional_exponent->(E(+|-|ɛ)digits)|ɛ
Num->digitsoptional_fractionoptional_exponent
5、关键字要被保留且在文法中以黑体出现
6、关系运算符(relop)指:
=、<、<>、<=、>=、>
7、Addop:
+、-、or
8、Mulop:
*、/、div、mod、and
9、Assignop:
:
=
3、词法分析程序详细设计及判别状态图
1、无符号数(可带小数和指数)的状态转换图:
2、
3、标识符/关键字的状态转换图:
程序详细设计:
4、开发环境
本程序在MicrosoftVisualC++6.0环境中编写,无特殊编译要求。
5、函数清单
voidLexcialAnalysis(FILE*fp);//词法分析主函数
intJudgeFirstLetter(charch);//判断单词的第一个字符
intIsDigit(charch);//判断是否为数字
intIsLetter(charch);//判断是否为字母
intIsSpecialPunc(charch);//判断是否为特殊标点
voidRecogDigit(charStrLine[]);//用状态图识别无符号数字
voidRecogIdentifier(charstrLine[]);//用状态图识别标识符
voidRecogPunc(charstrLine[]);//识别特殊标点
intIsKeyWord(stringstr);//判断标识符是否为关键字
voiderror();//出错处理
6、测试程序
programexample(input,output);
{commentsgoeshere!
}
varx,y:
integer;
functiongcd(a,b:
integer):
integer;
begin
ifb=1.2e3thengcd:
=a
elsegcd:
=gcd(b,amodb)
end;
begin
read(x,y);
write(gcd(x,y));
end.
7、运行效果
8、实验总结
通过这次编译器词法分析程序的编写,我更好地了解了词法分析的作用及工作原理,讲课本中的知识融入到程序编写过程中,理论结合了实际。
最先的时候觉得自己没有学过编译原理也可以写出语法分析,觉得书上的理论没有用,但是状态转换图则以一种十分规范的分析方式来分析程序,这样的做法应该是让词法分析从简单的程序实现上升到理论.而不仅仅拘泥于程序语言范畴之内.自己通过状态转换图识别单词和数字的过程,我觉得这种思想是值得我们借鉴的,很美妙。
当然,本次实验由于能力、时间等多方面因素只是实现了一个简单的词法分析程序,很多地方还不是很完善,如错误处理等。
此外,在编写词法分析程序的过程中,我遇到不少的问题,通过不断地调试才得以解决,锻炼了我调试程序的能力,这个能力是很难得的。
实验二语法分析
1、实验目的
通过设计、编写和调试自顶向下语法分析程序,了解一般自顶向下语法分析程序的组成以及对文法的要求,掌握从给定文法出发构造相应的预测分析表的方法。
2、实验设计
本次语法分析实验我选用自顶向下的LL
(1)预测分析方法,该方法实现的语法分析程序最主要的一点就是能构造出其文法对应的预测分析表,只有正确的预测分析表,才能得到正确的语法分析结果。
我使用了一个队列(Queue)来存放词法分析的结果,在词法分析过程中就开始维护该队列,然后在语法分析的时候,从队列中读取词法分析的结果。
此外,我还定义了一个分析栈,供语法分析过程使用。
3、文法规则
终结符(VT)
1.保留关键字
Programconstdobeginendcallifelsethenfunctionvarwhileintreal
特殊标点:
;:
.()
其他
assignop:
=mulop*、/、div、mod、andaddop+、-、orrelop=、<>、<、<=、>=、>.(012345)Id变量名num数字
非终结符
P(program)Ds(declarations)Subp_Ds(subprogram_declarations)C_S(compound_statement)ID_L(id_list)T(type)Subp_D(subprogram_delaclation)Subp_H(subprogram_head)A(arguments)P_L(parameter_list)OP_S(optional_statement)S_L(starement_list)S(statement)P_S(procedure_statememt)E_L(expression_list)E(expression)S_E(simple_expression)Tm(term)F(factor)
消除左递归后产生的新的非终结符
ID_L’,P_L’,S_L’,E_L’,S_E’Tm’,E’,F’
改进后文法:
1.P->programid(ID_L);DsSubp_DsC_S.
2.ID_L->idID_L’
3.ID_L’->,idID_L’
4.ID_L’->
ɛ
5.Ds->varID_L:
T;Ds
6.Ds->ɛ
7.T->integer
8.T->real
9.Subp_Ds->Subp_D;Subp_Ds
10.Subp_Ds->ɛ
11.Subp_D->Subp_HDsC_S
12.Subp_H->functionidA:
T;
13.A->(P_L)
14.A->ɛ
15.P_L->ID_L:
TP_L’
16.P_L‘->;ID_L:
TP_L’
17.P_L’->ɛ
18.C_S->beginOP_Send
19.OP_S->S_L
20.OP_S->ɛ
21.S_L->SS_L’
22.S_L’->;SS_L’
23.S_L’->ɛ
24.S–>idP_S
25.P_S->assignopE
26.P_S->(E_L)
27.S->C_S
28.S->ifEthenSelseS
29.S->whileEdoS
30.E_L->EE_L’
31.E_L’->,EE_L’
32.E_L’->ɛ
33.E->S_EE’
34.E’->relopS_E
35.E’->ɛ
36.S_E->TmS_E’
37.S_E’->addopTmS_E’
38.S_E’->ɛ
39.Tm->FTm’
40.Tm’->mulopFTm’
41.Tm’->ɛ
42.F->idF’
43.F’->(E_L)
44.F’->ɛ
45.F->ɛ
46.F->(E)
47.F->notF
以上文法构造出预测分析表,然后在程序中维护该预测分析表。
(预测分析表见最后或源程序)
4、函数清单及数据结构
structQueue//定义一个队列
{
intfront;
intrear;
string*str;
};
voidInitQueue(Queue&q,intQueueSize)//初始化队列
{
q.front=q.rear=0;
q.str=newstring[QueueSize];
}
voidEnQueue(Queue&q,stringstr)//进队
{
q.str[q.rear]=str;
q.rear++;
}
voidDeQueue(Queue&q,string&str)//出队
{
str=q.str[q.front];
q.front++;
}
typedefstruct//定义分析栈
{
intbase;
inttop;
symbol*symbol;
}Stack;
voidGetTop(Stacks,symbol&symbol)//获得栈顶元素
{
if(s.base==s.top)
{
cout<<"栈为空";
return;
}
symbol=s.symbol[s.top];
}
voidPush(Stack&s,symbolsymbol)//进栈
{
s.top++;
s.symbol[s.top]=symbol;
}
voidPop(Stack&s,symbol&symbol)//出栈
{
if(s.base==s.top)
{
cout<<"栈为空";
return;
}
symbol=s.symbol[s.top];
s.top--;
}
structProduction//定义一个产生式结构体
{
stringhead;
stringbody;
};
voidInitPaserTable(Production(*p)[25]);//维护一张预测分析表
intHash(stringstr)//返回对应字符的行列数用于预测分析表的定位
voidSyntaxAnalysis();//语法分析程序
voidmain()//main函数中调用词法分析程序和语法分析程序
{
FILE*fp;
while(TRUE)
{
//cin>>fNamePath;
if((fp=fopen("ex.cpp","r"))!
=NULL)//文件可读就跳出循环
break;
elsecout<<"文件路径错误!
请输入源文件名(包括路径和后缀名):
";
}
LexcialAnalysis(fp);//词法分析
SyntaxAnalysis();//语法分析
}
5、运行效果
由于结果很长这里只贴上部分截屏
6、实验总结
通过本次设计、编写和调试语法分析程序的过程,我了解了一般自顶向下语法分析程序的组成以及对文法的要求,掌握了从给定文法出发构造相应的预测分析表的方法。
如构造First集、Follow集、Select集和LL
(1)预测分析表。
了解了语法分析的具体过程。
由于时间的原因,我的语法分析程序还并不完善,出错处理还不是面面俱到,待以后有时间再完善也是一次不错的锻炼。
在语法分析的学习中,通过对自顶向下和自底向上理解,让我领悟了一些有价值的考虑问题的方法.在我看来编译原理从本质上来讲就是算法问题,本次的实验大多也都是算法思想的体现,只是由于编译器的复杂性,算法复杂性很高而已,不知道这样理解是不是很幼稚。
回到本次程序的语法层上,利用的LL也就是从文法的起始符号开始反复使用产生式进行推导直至推导出输入符号串.自上而下分析通常要求文法的产生式不含左递归,否则会使分析程序死循环,所以先要对文法进行必要的化简,然后根据所得的状态转移图来编制程序,以前程序很多时候都是看题目后直接上手,这次编程步骤的条理性的确又上升了一个层次.所以这次小的课程设计从另外一方面也加强了我的程序设计功底。
编译原理上机就此告一段落,虽然在编写代码上用的时间不像课程那样长,但在编写程序期间的感受颇多。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 词法 分析