编译原理词法分析实验报告.docx
- 文档编号:15829231
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:16
- 大小:36.08KB
编译原理词法分析实验报告.docx
《编译原理词法分析实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析实验报告.docx(16页珍藏版)》请在冰点文库上搜索。
编译原理词法分析实验报告
实验一词法分析
一、实验目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
二、实验内容
(1)功能描述:
该程序是实现一个词法分析器,词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是将单词分为五种的方法。
识别关键字:
main、if、int、for、while、do、return、break、continue;
单词种别码为1。
标识符:
单词种别码为2。
常数:
为无符号整形数;单词种别码为3。
运算符:
包括:
+、-、*、/、=、>、<、>=、<=、!
=;单词种别码为4。
分隔符:
包括:
、;、{、}、(、);单词种别码为5。
(2)程序结构描述:
输入:
从控制台输入一段源程序代码,对输入的代码进行词法分析,
处理:
分离出关键字、标识符、数值、运算符和界符。
输出:
在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。
其中,编码是自定义的,一种类型对应一个编码。
词法分析结果显示在控制台上。
(3)程序设计思路
1、定义编码表,用ArrayList集合存放单词,如:
关键字、运算符、分界符。
这三种单词是固定的,标示符和数字这两种单词不存放在集合中。
编码表是固定的,只需要初始化一次就够了,所以将集合定义为static类型,使其在类加载时,进行一次初始化。
2、staticcharallstr[]=newchar[100000];该数组用于存储用户从控制台输入的所有字符。
3、//从键盘获取一个一个的字符
publiccharGetchar(){
try{
ch=(char)System.in.read();
}catch(Exceptione){
e.printStackTrace();
}
returnch;
}
4、用while循环遍历allstr数组中存放的字符,判断分离出关键字、标示符、数字、运算符、标示符。
5、Reserve()遍历编码表,查询单词的编码号。
3、实验过程记录
实验过程中,比较费力的是如何分割出一个一个的单词,定义一个变量j来记录一个单词在allstr数组中的起始位置,变量index来判定一个单词是否到结尾位置。
用String类中的subString(str,start,end)方法来截取一个单词。
一旦一个单词的下标移动错误,导致后面识别出的单词全都不正确。
通过加断点,对程序一步一步的调试,查看j、index变量的值的变化。
一步一步的分析,最终得到了正确的运行结果。
测试数据:
main()
{
inta,b;
a=10;
b=b+a;
}#
运行结果:
测试数据:
Intabc(){
Inta=5,b=6;
While(a>=0){
a--;
}
Returnb;
}#
运行结果:
==>>>
测试数据:
inta=10,b=5;
if(a>=9)
returnb;#
运行结果:
四、主要源代码
//判断是否为字母
publicbooleanIsLetter(charch){
returnjava.lang.Character.isLetter(ch);
}
//判断是否为数字
publicbooleanIsDigit(charch){
returnjava.lang.Character.isDigit(ch);
}
publicintReserve(){
name=newString(allstr).substring(j,index);//取子串
for(inti=0;i<5;i++)
if(table[i].key.contains(name))
returntable[i].code;
return0;
}
publicstaticvoidmain(String[]args){
WordAnalyzera=newWordAnalyzer();
ch=a.Getchar();
intm=0;
while(ch!
='#'){
allstr[index]=ch;
index++;
ch=a.Getchar();}
intk=index;
index=0;
while(j m=j; //标示符 if(a.IsLetter(allstr[j])){ while(a.IsLetter(allstr[index])||a.IsDigit(allstr[index])){ index++; } if(a.Reserve()! =0) System.out.println("("+a.Reserve()+","+name+")"); else System.out.println("(2,"+name+")"); j=index; } //数字 if(a.IsDigit(allstr[j])){ while(a.IsDigit(allstr[index])) index++; if(a.Reserve()! =0) System.out.println("("+a.Reserve()+","+name+")"); else System.out.println("(3,"+name+")"); j=index; //识别分界符 //判断'(' if(allstr[j]=='('){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } 。 。 。 。 。 。 //识别运算符 //判断=和== if(allstr[j]=='='){ index++; if(allstr[index]=='='){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; }else{ System.out.println("("+a.Reserve()+","+name+")"); j=index; }} 。 。 。 。 。 。 5、实验总结 做本次实验大约用了三个小时,用了一个多小时思考,设计,查资料,剩余的时间来编码。 由于刚开始对问题的理解不太深入,造成在编码过程中出现了很多问题,一直在考虑是用一个单词一个编码还是将单词分为五种编码,浪费了很长时间,最后选择了将单词分为五种编码的方法来编写词法分析,因为一个编码对应多个单词,考虑到用键值对的形式来存放编码列表。 多个固定的单词用ArrayList集合来存储,这些编码数据是固定的,所以定义为static类型,只需要初始化一次。 在试验中最困难的就是分离出关键字、标识符、数字、运算符和分界符,通过调试观察变量的值,修改,调试,运行。 来回重复,最后的得到了正确的运行结果。 packagecom.fgy.practice; importjava.util.ArrayList; importjava.util.List; publicclassWordAnalyzer{ staticcharch; staticintindex=0; staticintj=0; staticcharallstr[]=newchar[100000]; staticStringname; staticKeyTable[]table=newKeyTable[5]; static{ List al.add("main"); al.add("if"); al.add("else"); al.add("int"); al.add("for"); al.add("while"); al.add("return"); List List List al3.add("+"); al3.add("++"); al3.add("-"); al3.add("--"); al3.add("="); al3.add("=="); al3.add(">"); al3.add(">="); al3.add("<"); al3.add("<="); List al4.add(","); al4.add(";"); al4.add("{"); al4.add("}"); al4.add("("); al4.add(")"); table[0]=newKeyTable(al,1);//关键字 table[1]=newKeyTable(al1,2);//标示符 table[2]=newKeyTable(al2,3);//常数 table[3]=newKeyTable(al3,4);//运算符 table[4]=newKeyTable(al4,5);//分界符 } //从键盘获取一个一个的字符 publiccharGetchar(){ try{ ch=(char)System.in.read(); }catch(Exceptione){ e.printStackTrace(); } returnch; } //判断是否为字母 publicbooleanIsLetter(charch){ returnjava.lang.Character.isLetter(ch); } //判断是否为数字 publicbooleanIsDigit(charch){ returnjava.lang.Character.isDigit(ch); } publicintReserve(){ name=newString(allstr).substring(j,index);//取子串 for(inti=0;i<5;i++) if(table[i].key.contains(name)) returntable[i].code; return0; } publicstaticvoidmain(String[]args){ WordAnalyzera=newWordAnalyzer(); ch=a.Getchar(); intm=0; while(ch! ='#'){ allstr[index]=ch; index++; ch=a.Getchar(); } intk=index; index=0; while(j m=j; //标示符 if(a.IsLetter(allstr[j])){ while(a.IsLetter(allstr[index])||a.IsDigit(allstr[index])){ index++; } if(a.Reserve()! =0) System.out.println("("+a.Reserve()+","+name+")"); else System.out.println("(2,"+name+")"); j=index; } //数字 if(a.IsDigit(allstr[j])){ while(a.IsDigit(allstr[index])) index++; if(a.Reserve()! =0) System.out.println("("+a.Reserve()+","+name+")"); else System.out.println("(3,"+name+")"); j=index; } //识别分界符 //判断'(' if(allstr[j]=='('){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } //判断')' if(allstr[j]==')'){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } //判断‘{’ if(allstr[j]=='{'){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } //判断‘}’ if(allstr[j]=='}'){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } //判断; if(allstr[j]==';'){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } //判断, if(allstr[j]==','){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; } //识别运算符 //判断=和== if(allstr[j]=='='){ index++; if(allstr[index]=='='){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; }else{ System.out.println("("+a.Reserve()+","+name+")"); j=index; } } //判断'<'和‘<=’ if(allstr[j]=='<'){ index++; if(allstr[index]=='='){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; }else{ System.out.println("("+a.Reserve()+","+name+")"); j=index; } } //判断‘>’和‘>=’ if(allstr[j]=='>'){ index++; if(allstr[index]=='='){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; }else{ System.out.println("("+a.Reserve()+","+name+")"); j=index; } } //判断‘+’和‘++’ if(allstr[j]=='+'){ index++; if(allstr[index]=='+'){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; }else{ System.out.println("("+a.Reserve()+","+name+")"); j=index; } } //判断‘-’和‘--’ if(allstr[j]=='-'){ index++; if(allstr[index]=='-'){ index++; System.out.println("("+a.Reserve()+","+name+")"); j=index; }else{ System.out.println("("+a.Reserve()+","+name+")"); j=index; } //判断空格'' if(allstr[j]==''){ while(allstr[j]==''){ index++; j=index; } } } //判断是不是换行 if(allstr[j]=='\n'){ index++; j=index; } if(m==j){ index++; j=index; } } } } classKeyTable{ List intcode; publicKeyTable(List this.key=key; this.code=code; } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 词法 分析 实验 报告