编译原理课程设计词法分析之基于Lex实现词法分析.docx
《编译原理课程设计词法分析之基于Lex实现词法分析.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计词法分析之基于Lex实现词法分析.docx(12页珍藏版)》请在冰豆网上搜索。
![编译原理课程设计词法分析之基于Lex实现词法分析.docx](https://file1.bdocx.com/fileroot1/2022-11/26/bade3d3c-8bb7-46e9-9cc4-267308e881c1/bade3d3c-8bb7-46e9-9cc4-267308e881c11.gif)
编译原理课程设计词法分析之基于Lex实现词法分析
课程设计说明书
设计题目:
编译原理课程设计
专业:
计算机科学与技术班级:
设计人:
学号:
山东科技大学
2015年7月12日
课程设计任务书
学院信息科学与工程学院专业计算机科学与技术班级2012-2姓名高世军
一、课程设计题目:
编译原理课程设计
二、课程设计主要参考资料
(1)韩太鲁等,编译原理.石油大学出版社.2007.9
(2)
(3)
三、课程设计应解决的主要问题:
(1)词法分析之基于Lex实现词法分析
(2)词法分析之基于文法的实现
(3)语法分析之LL1分析法实现
(4)
四、课程设计相关附件(如:
图纸、软件等):
(1)vc++6.0
(2)ParserGenerator
五、任务发出日期:
2015-7-5课程设计完成日期:
2015-7-12
指导教师签字:
系主任签字:
指导教师对课程设计的评语
成绩:
指导教师签字:
年月日
词法分析之基于Lex实现词法分析
一、设计目的
通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解成各类单词的词法分析方法。
二、设计要求
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
三、设计说明
1.需求分析
a)输入及其范围
Lex输入文件由3个部分组成:
定义集(definition),规则集(rule)和辅助程序集(auxiliaryroutine)或用户程序集(userroutine)。
这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下
{definitions}
%%
{rules}
%%
{auxiliaryroutines}
范围:
识别保留字:
if、int、for、while、do、return等保留字类别码为1。
其他的都识别为标识符;单词类别码为2。
常数为无符号整形数;单词类别码为3。
运算符包括:
+、-、*、/、=、>、<、>=、<=、!
=;类别码为4。
分隔符包括:
、;、{、}、(、);类别码为5。
错误字符类别码为6。
b)输出形式
([数字],“单词“)数字代表所识别的单词所属的类型。
c)程序功能
读取文件中的源程序,然后对源程序分析,输出分析结果。
d)测试数据
将测试数据写在文本文件中,测试为程序的输入数据。
2.概要设计
a)数据类型的定义
//定义集,包括头文件和变量定义
%{
#include
#include
#include
#include
intlineno=1;//定义行号
%}
//定义正则表达式
letter[A-Za-z]//字母
digit[0-9]//数字
id({letter}|[_])({letter}|{digit}|[_])*//开头为字母的标识符
error_id({digit})+({letter})+//开头为数字的错误标识符
num{digit}+//数字集合
whitespace[\t]+//空格
enter[\n]+//回车
//定义识别规则
%%
b)主程序流程
c)模块间的调用关系
3.详细设计
主体代码部分:
%%
//识别关键字
{key}
{printf("%d行",linenum);//打印行号
printf("%s关键字\n",yytext);}//输出关键字
//识别数字
{num}
{printf("%d行",linenum);//打印行号
printf("%s数字\n",yytext);}//输出数字
//识别关系运算符
{guanxi}
{printf("%d行",linenum);//打印行号
printf("%s关系运算符\n",yytext);}//输出关系运算符
//识别关系运算符
{suanshu}
{printf("%d行",linenum);//打印行号
printf("%s算术运算符\n",yytext);}//输出算术运算符
//识别分界符
{fenjie}
{printf("%d行",linenum);//打印行号
printf("%s关系运算符\n",yytext);}//输出分界符
//识别注释符
{zhushi}
{printf("%d行",linenum);//打印行号
printf("%s注释符\n",yytext);}//输出注释符号
//识别标识符
{id}
{printf("%d行",linenum);//打印行号
printf("%s标志符号\n",yytext);}//打印标识符
//识别错误的标识符
{error}
{printf("%d行",linenum);
printf("error:
%s\n",yytext);}
//识别空格
{whitespace}
{}//忽略空格
//识别换行
{enter}
{linenum++;}//遇到回车行号自动加1
四、运行结果及分析
1.测试数据
在test.txt文件中写入如下数据。
voidmain()
{intx;inty;
x=input();y=intput();
output(gcd(x,y));}
2.测试输出的结果
3.设计与思考
基于lex的词法分析,一个模块定义好了之后,其他模块也就出来了。
难点在于正则表达式的设计,每个模块都有定义集,规则集和辅助程序集。
而且第一部分用“%{”和“%}”括起来。
第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。
五、总结
通过本次实验,学会了基于Lex的词法分析器构造方法。
在实验过程中,万事开头难,刚开始不知道怎么做,以及不知道如何使用老师给的软件,在仔细分析了需求之后,查找了一些关于ParserGenarator2软件的使用方法,很快的连接好了VC6.0和ParserGenarator2.然后输入简单的程序对其进行了测试,成功后,给自己极大地信心继续完成接下来的实验,参考了资料的源程序之后,动手开始写自己的代码,最终一步步实现能够达到要求的程序。
经过程序的书写,使我了解了Lex语言。
了解了基于LEX语言的词法分析程序构造的重要性,对今后的学习和工作有很大的帮助。
词法分析之基于文法的实现
一、设计目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
二、设计要求
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
三、设计说明
1.需求分析:
a)输入及其范围
识别保留字:
if、int、for、while、do、return、break、continue等;
保留字类别码为1。
其他的都识别为标识符;单词类别码为2。
常数为无符号整形数;单词类别码为3。
运算符包括:
+、-、*、/、=、>、<、>=、<=、!
=;类别码为4。
分隔符包括:
、;、{、}、(、);类别码为5。
错误字符类别码为6。
b)输出形式
词法分析器的单词符号常常表示成以下的二元式(单词类别码,单词符号的属性值)。
本实验中,可采用的是一大类符号一类别码的方式。
c)程序功能
词法分析器的功能是输入源程序,输出单词符号。
d)测试数据
测试输入的程序为:
main()
{
inta,b;
a=10;
b=a+20;
}
2.概要设计
a)数据类型的定义
定义三个字符串,用于输入程序单词的匹配。
stringRword[RWD]={"if","int","for","while","do","return","break","continue"};
stringOpear[OPEAR]={"+","-","*","/","=",">","<",">=","<=","!
=","=="};
stringSepar[SEPAR]={",",";","{","}","(",")"};
b)主程序流程
3.详细设计
voidmain()
{
vectorinput;
vector:
:
iteratoriter;
/*将源代码中的单词从文件中读出按成分存放在input中*/
ifstreammyf;
stringstr="";
myf.open("test.txt");
if(myf.fail())
{
cout<<"error!
"<}
charch;
ch=myf.get();
while(!
myf.eof())
{
for(inti=0;i{
stringtemp="";
temp+=ch;
if(temp==Separ[i])
{
if(str!
="")
{
input.push_back(str);
str="";
}
str=ch;
input.push_back(str);
str="";
ch=myf.get();
break;
}
}
if(ch=='\t'||ch==''||ch=='\n')//判断是否为空格,回车
{
if(str!
="")
{
input.push_back(str);
str="";
}
ch=myf.get();
}
elseif(ch=='!
'||ch=='>'||ch=='<'||ch=='=')//判断是否为运算符
{
if(str!
="")
{
input.push_back(str);
str="";
}
str=ch;
ch=myf.get();
if(ch=='=')
{
str+=ch;
input.push_back(str);
ch=myf.get();
str="";
}
else
{
input.push_back(str);
}
}
elseif(ch=='+'||ch=='-'||ch=='*'||ch=='/')