实验一 词法分析设计.docx
- 文档编号:9661364
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:34
- 大小:173.79KB
实验一 词法分析设计.docx
《实验一 词法分析设计.docx》由会员分享,可在线阅读,更多相关《实验一 词法分析设计.docx(34页珍藏版)》请在冰点文库上搜索。
实验一词法分析设计
实验一词法分析设计
一、实验目的
通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二、实验内容
用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。
通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。
以下是实现词法分析设计的主要工作:
(1)从源程序文件中读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)按拼写单词,并用(内码,属性)二元式表示。
(属性值——token的机内表示)
(5)如果发现错误则报告出错
(6)根据需要是否填写标识符表供以后各阶段使用。
单词的基本分类:
◆关键字:
由程序语言定义的具有固定意义的标识符。
也称为保留字例如if、for、while、printf;单词种别码为1。
◆标识符:
用以表示各种名字,如变量名、数组名、函数名;
◆常数:
任何数值常数。
如125,1,0.5,3.1416;
◆运算符:
+、-、*、/;
◆关系运算符:
<、<=、=、>、>=、<>;
◆分界符:
;、,、(、)、[、];
三、词法分析实验设计思想及算法
1、主程序设计考虑:
◆程序的说明部分为各种表格和变量安排空间。
在具体实现时,将各类单词设计成结构和长度均相同的形式,较短的关键字后面补空。
k数组------关键字表,每个数组元素存放一个关键字(事先构造好关键字表)。
s数组------存放分界符表(可事先构造好分界符表)。
为了简单起见,分界符、算术运算符和关系运算符都放在s表中(编程时,应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。
id和ci数组分别存放标识符和常数。
instring数组为输入源程序的单词缓存。
outtoken记录为输出内部表示缓存。
还有一些为造表填表设置的变量。
◆主程序开始后,先以人工方式输入关键字,造k表;再输入分界符等造p表。
◆主程序的工作部分设计成便于调试的循环结构。
每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。
例如,把每一单词设计成如下形式:
(type,pointer)
其中type指明单词的种类,例如:
Pointer指向本单词存放处的开始位置。
还有一些为造表填表设置的变量。
◆主程序开始后,先以人工方式输入关键字,造k表;再输入分界符等造p表。
◆主程序的工作部分设计成便于调试的循环结构。
每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。
例如,把每一单词设计成如下形式:
(type,pointer)
其中type指明单词的种类,例如:
Pointer指向本单词存放处的开始位置。
词法分析设计流程图
2、词法分析过程考虑
◆根据输入单词的第一个字符(有时还需读第二个字符),
判断单词类,产生类号:
以字符k表示关键字;id表示标识符;
ci表示常数;s表示分界符。
◆对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id中,将常数变为二进制形式存入数组中ci中,并记录其在表中的位置。
lexical过程中嵌有两个小过程:
一个名为getchar,其功能为从instring中按顺序取出一个字符,并将其指针pint加1;另一个名为error,当出现错误时,调用这个过程,输出错误编号。
◆要求:
所有识别出的单词都用两个字节的等长表示,称为内部码。
第一个字节为t,第二个字节为i。
t为单词的种类。
关键字的t=1;分界符的t=2;算术运算符的t=3;关系运算符的t=4;无符号数的t=5;标识符的t=6。
i为该单词在各自表中的指针或内部码值。
表1为关键字表;表2为分界符表;表3为算术运算符的i值;表4为关系运算符的i值。
取字符和统计字符行列位置子程序
四、实验要求
1、编程时注意编程风格:
空行的使用、注释的使用、缩进的使用等。
2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。
3、根据测试数据进行测试。
测试实例应包括以下三个部分:
◆全部合法的输入。
◆各种组合的非法输入。
◆由记号组成的句子。
4、词法分析程序设计要求输出形式:
例:
输入VC++语言的实例程序:
Ifi=0thenn++;
a﹤=3b%);
输出形式为:
单词二元序列类型位置(行,列)
(单词种别,单词属性)
for(1,for)关键字(1,1)
i(6,i)标识符(1,2)
=(4,=)关系运算符(1,3)
0(5,0)常数(1,4)
then(1,then)关键字(1,5)
n(6,n)标识符(1,6)
++ErrorError(1,7)
;(2,;)分界符(1,8)
a(6,a)标识符(2,1)
﹤=(4,<=)关系运算符(2,2)
3bErrorError(2,4)
%ErrorError(2,4)
)(2,))分界符(2,5)
;(2,;)分界符(2,6)
五、实验步骤
1、根据流程图编写出各个模块的源程序代码上机调试。
2、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计的词法分析程序;直至能够得到完全满意的结果。
3、书写实验报告;实验报告正文的内容:
◆功能描述:
该程序具有什么功能?
◆程序结构描述:
函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。
◆详细的算法描述(程序总体执行流程图)。
◆给出软件的测试方法和测试结果。
◆实验总结(设计的特点、不足、收获与体会)。
六、源程序
1、词法分析器操作类(Morp_Opertion.java)
packageMorphologyAnalysis;
importjava.util.ArrayList;
publicclassMorp_Opertion{
privateArrayList
privateArrayList
privateArrayList
privateArrayList
privatefinalchar[]letterTable={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'
'q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L'
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};//字母表
privatefinalchar[]digitTable={'1','2','3','4','5','6','7','8','9','0'};//数字表
privatefinalchar[]arithmeticTable={'+','-','*','/'};//算数运算符表
privatefinalchar[]relationTable={'<','=','>'};//关系运算符表
privatecharch;//待判断的字符
privateStringtoken;//带判断的字符串
privateintindex=0;//标志指针
privatechar[]strChar=newchar[1000];//存放单行的字符
privateintrowLength=0;//单行字符长度
privateStringresult=newString();//存放分析结果
privateString[][]dataStrings=newString[100000][5];//存放表格数据
privateintarrarycount=0;//存放表格行数
/**
*@returntheresult
*/
publicStringgetResult(){
returnresult;
}
/**
*@paramresulttheresulttoset
*/
publicvoidsetResult(Stringresult){
this.result=result;
}
/**
*@returnthearrarycount
*/
publicintgetArrarycount(){
returnarrarycount;
}
/**
*@paramarrarycountthearrarycounttoset
*/
publicvoidsetArrarycount(intarrarycount){
this.arrarycount=arrarycount;
}
publicMorp_Opertion(){
this.result+="单词\t二元序列\t\t类型\t\t位置(行,列)\r\n";
}
//向关键词表、分界符表、标识符表、常数表插入数据
publicvoidinKeyTable(Stringkey){
if(isKey(key)){
return;
}else{
keyTable.add(key);
}
}
publicvoidinDelimiterTable(Stringdelimiter){
if(isDelimiter(delimiter)){
return;
}else{
delimiterTable.add(delimiter);
}
}
publicvoidinIdentifierTable(Stringidentifier){
if(isIdentifier(identifier)){
return;
}else{
identifierTable.add(identifier);
}
}
publicvoidinConstDigitTable(StringconstDigit){
if(isConstDigit(constDigit)){
return;
}else{
constDigitTable.add(constDigit);
}
}
//判断字符是否为字母
publicbooleanisLetter(Stringword){
intN=0;
while(N if(word.charAt(0)==letterTable[N]){ returntrue; } N++; } returnfalse; } //判断字符是否为数字 publicbooleanisDigit(Stringword){ intN=0; while(N if(word.charAt(0)==digitTable[N]){ returntrue; } N++; } returnfalse; } //判断字符串是否在关键词表 publicbooleanisKey(Stringword){ intN=0; while(N if(word.equals(keyTable.get(N))){ returntrue; } N++; } returnfalse; } //判断字符串是否在分界符表 publicbooleanisDelimiter(Stringword){ intN=0; while(N if(word.equals(delimiterTable.get(N))){ returntrue; } N++; } returnfalse; } //判断字符串是否在标识符表 publicbooleanisIdentifier(Stringword){ intN=0; while(N if(word.equals(identifierTable.get(N))){ returntrue; } N++; } returnfalse; } //判断字符串是否在常数表 publicbooleanisConstDigit(Stringword){ intN=0; while(N if(word.equals(constDigitTable.get(N))){ returntrue; } N++; } returnfalse; } //判断字符是否为算数运算符 publicbooleanisArithmetic(Stringword){ intN=0; while(N if(word.charAt(0)==arithmeticTable[N]){ returntrue; } N++; } returnfalse; } //判断字符是否为关系运算符 publicbooleanisRelation(Stringword){ intN=0; while(N if(word.charAt(0)==relationTable[N]){ returntrue; } N++; } returnfalse; } //清理分析器 publicvoidcleanAnalysis(){ this.ch=''; this.index=0; this.result=""; this.rowLength=0; this.strChar=null; } //获得非空白字符 publicchargetBC(char[]strChar){ try{ while((strChar[this.index])==''){ this.index++; } this.index++; }catch(ArrayIndexOutOfBoundsExceptione){ return';'; } returnstrChar[this.index-1]; } //链接字符串和字符 publicStringcontact(Stringtoken,charch){ returntoken+String.valueOf(ch); } //获得下一个字符 publicchargetNextChar(char[]strChar){ if(this.index<=this.rowLength-1){ this.index++; returnstrChar[this.index-1]; }else{ this.index++; return''; } } //回调一个字符 publicvoidretract(){ this.index--; } //单行分析 publicStringrowAnalysis(Stringrow,intN){ intM=0; strChar=row.toCharArray(); rowLength=row.length(); while(index this.token=""; this.ch=this.getBC(strChar); if(this.isLetter(String.valueOf(this.ch))){ this.token=this.contact(this.token,this.ch); this.ch=this.getNextChar(this.strChar); while(isLetter(String.valueOf(this.ch))||isDigit(String.valueOf(this.ch))){ this.token=this.contact(this.token,this.ch); this.ch=this.getNextChar(this.strChar); } this.retract(); if(this.isKey(token)){ this.result+=this.token.toString()+"\t(1,"+this.token.toString()+")\t\t" +"关键词\t\t"+"("+N+","+++M+")"+"\r\n"; this.getDataStrings()[arrarycount][0]=""; this.getDataStrings()[arrarycount][1]=this.token.toString(); this.getDataStrings()[arrarycount][2]="(1,"+this.token.toString()+")"; this.getDataStrings()[arrarycount][3]="关键词"; this.getDataStrings()[arrarycount][4]="("+N+","+M+")"; arrarycount++; }else{ this.inIdentifierTable(token); this.result+=this.token.toString()+"\t(6,"+this.token.toString()+")\t\t" +"标识符\t\t"+"("+N+","+++M+")"+"\r\n"; this.getDataStrings()[arrarycount][0]=""; this.getDataStrings()[arrarycount][1]=this.token.toString(); this.getDataStrings()[arrarycount][2]="(6,"+this.token.toString()+")"; this.getDataStrings()[arrarycount][3]="标识符"; this.getDataStrings()[arrarycount][4]="("+N+","+M+")"; arrarycount++; } this.token=""; }elseif(this.isDigit(String.valueOf(this.ch))){ this.token=this.contact(this.token,this.ch); this.ch=this.getNextChar(strChar); while(this.isDigit(String.valueOf(this.ch))){ this.token=this.contact(this.token,this.ch); this.ch=this.getNextChar(this.strChar); } this.retract(); this.inConstDigitTable(token); this.result+=this.token.toString()+"\t(5,"+this.token.toString()+")\t\t" +"常数\t\t"+"("+N+","+++M+")"+"\r\n"; this.getDataStrings()[arrarycount][0]=""; this.getDataStrings()[arrarycount][1]=this.token.toString(); this.getDataStrings()[arrarycount][2]="(5,"+this.token.toString()+")"; this.getDataStrings()[arrarycount][3]="常数"; this.getDataStrings()[arrarycount][4]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验一 词法分析设计 实验 词法 分析 设计