编译原理综训报告词法分析器.docx
- 文档编号:24243408
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:27
- 大小:203.34KB
编译原理综训报告词法分析器.docx
《编译原理综训报告词法分析器.docx》由会员分享,可在线阅读,更多相关《编译原理综训报告词法分析器.docx(27页珍藏版)》请在冰豆网上搜索。
编译原理综训报告词法分析器
软件学院
综合训练项目报告书
课程名称编译原理
项目名称词法分析器的设计
专业班级
组别
姓名
成员
任课教师郭伟
2015年6月
1设计时间
2015年6月24
2设计任务
编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用Lex等工具自动生成。
从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token),把源程序变为等价的标记串序列。
执行词法分析的程序称为词法分析器,也称为扫描器。
词法分析是所有分析优化的基础,涉及的知识较少,如状态转换图等,易于实现。
本次实验使用java代码实现。
3设计内容
3.1设计要求
掌握词法分析设计的基本原理及思想,巩固所学的理论知识,培养综合运用所学知识解决实际问题的能力。
设计要求:
1)用C语言开发一个词法分析程序,词法分析程序可以分析包含以下符号测试代码;
关键字:
if、int、for、while、do、return、break、continue;单词种别码为1。
标识符;单词种别码为2。
常数为无符号整形数;单词种别码为3。
分隔符包括:
、;、{、}、(、);单词种别码为4。
运算符包括:
+、-、*、/、=、、<、=、<=、!
=;单词种别码为5。
2)以<种别码,值>的形式存储符号表;
3)删除注释、空格和无用符号 ,将删除后的程序代码输出在控制台上;
4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行,将错误信息(错误信息为错误种类,错误种类包括未知的标识符、操作符、错误格式)输出到屏幕上;
5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),在控制台中输出的符号表(来自测试代码中出现的符号)。
其中符号表含有的属性列为:
单词符号和种别码。
3.2问题分析
3.2.1单词的构词规则
对某特定语言A,构造其词法规则。
A的内容如下:
表1构词规则表
该语言的单词符号包括
1、关键字
if
int
for
while
do
return
break
continue
表2关键字表
2、运算符及界符
表3运算符及界符表
3、标识符(字母大小写不敏感),整型常数
3.2.2词汇表
对于后文正则式中可能出现的符号定义如下,以便清晰地描述A语言的正则式
符号
说明
a
字母
b
数字
c
符号(不包括字母和数字)
*
闭包运算符
|
或运算符
.
连接运算符(可省略)
空
#
结束符
表4词汇表
3.2.3单词种别定义
if
1
contine
1
)
4
!
=
5
int
1
标识符
2
+
5
/
5
for
1
常数
3
*
5
;
5
while
1
,
4
-
5
do
1
{
4
=
5
return
1
}
4
<
5
break
1
(
4
<=
5
表5单词种别表
对于标识符或保留字的推导对于常数的推导
对于符号的推导
`
3.3程序设计
3.3.1总体设计
图一、扫描子程序主要部分流程
3.3.2状态转换图
图二读取状态转换
3.4测试与分析
3.4.1测试
我们对程序的测试如下,采用如下用例
用例:
运行结果为:
错误:
常数表:
标志符表:
保留字及符号对应的二元组表:
二元组及错误信息均无误,且注释成功跳过
`
3.5代码
publicclassCompilerextendsJFrameimplementsActionListener{
introw=1;
intline=1;
interr=0;
JMenuBarmb=newJMenuBar();
JMenufileMenu=newJMenu("文件");
JMenuactionMenu=newJMenu("词法分析");
JMenuItemcloseWindow=newJMenuItem("退出");
JMenuItemopenFile=newJMenuItem("打开");
JMenuItemlexical_check=newJMenuItem("开始");
intbegin=0;
intend=0;
TextAreatext=newTextArea();
TextAreaerror_text=newTextArea();
TextAreaend_text=newTextArea();
FileDialogfile_dialog_load=newFileDialog(this,"Openfile...",ileDialog.LOAD);
JPanelpan1=newJPanel();
JPanelpan2=newJPanel();
Compiler(){
this.add(end_text);end_text.setEditable(false);
this.add(text);
this.add(error_text);error_text.setEditable(false);
pan1.setLayout(newGridLayout(1,1));pan1.add(text);
pan2.setLayout(newGridLayout(2,1));
pan2.add(error_text,"North");
pan2.add(end_text,"South");
getContentPane().add(pan1,"West");
getContentPane().add(pan2,"Center");
this.setJMenuBar(mb);
mb.add(fileMenu);
mb.add(actionMenu);
fileMenu.add(openFile);
fileMenu.add(closeWindow);
actionMenu.add(lexical_check);
error_text.setText("----------------词法分析---------------------\n");
end_text.setText("-----------词法分析错误信息--------------\n");
closeWindow.addActionListener(this);
openFile.addActionListener(this);
lexical_check.addActionListener(this);
pack();
this.addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEvente){
System.exit(0);}
});
this.setVisible(true);}
publicstaticvoidmain(String[]args){
Compilercompiler=newCompiler();}
publicvoidactionPerformed(ActionEvente){
if(e.getSource()==closeWindow){
intflag=JOptionPane.showConfirmDialog(null,"是否退出");
System.out.println("flag="+flag);
if(flag==0){
System.exit(0);
}elseif(flag==1){
}
}elseif(e.getSource()==openFile){
file_dialog_load.setVisible(true);
Filemyfile=newFile(file_dialog_load.getDirectory(),file_dialog_load.getFile());
try{
BufferedReaderbufReader=newBufferedReader(newFileReader(myfile));
newtestxiaochu(myfile);
try{
neweryuandanci(myfile);
}catch(Exceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();}
Stringcontent="";
Stringstr;
while((str=bufReader.readLine())!
=null){
content+=str+"\n";
text.setText(content);
}
}catch(IOExceptionie){
System.out.println("IOexceptionoccurs...");
}
}elseif(e.getSource()==lexical_check){
error_text.setText("");
row=0;
line=1;
checkLexical();
}
}
publicvoidcheckLexical(){
Stringerror_info=error_text.getText();
Stringcontent=text.getText();
if(content.equals("")){
error_info+="文件尚未载入!
\n";
error_text.setText(error_info);
}else{
inti=0;//选择第i个字符进行检测。
intN=content.length();//文件大小
intstate=0;//状态标志
for(i=0;i row++; charc=content.charAt(i); switch(state){ case0: if(c==','||c==''||c=='\t'||c=='{'||c=='}'||c=='('|| c==')'||c==';'||c=='['||c==']'){ if(isDigit(content.charAt(i-1))&&isDigit(content.charAt(begin))){ end=i; error_text.append("\t数值\t"+"200"+ content.substring(begin,end)+'\n'); } if(c==',')error_text.append("\t界符\t"+"\t501"+"\t,"+'\n'); if(c==';')error_text.append("\t界符\t"+"\t502"+"\t;"+'\n'); if(c=='{')error_text.append("\t界符\t"+"\t503"+"\t{"+'\n'); if(c=='}')error_text.append("\t界符\t"+"\t504"+"\t}"+'\n'); if(c=='(')error_text.append("\t界符\t"+"\t505"+"\t("+'\n'); if(c==')')error_text.append("\t界符\t"+"\t506"+"\t)"+'\n'); if(c=='[')error_text.append("\t界符\t"+"\t508"+"\t["+'\n'); if(c==']')error_text.append("\t界符\t"+"\t509"+"\t]"+'\n'); state=0; }elseif(c=='+')state=1; elseif(c=='-')state=2; elseif(c=='*')state=3; elseif(c=='/')state=4; elseif(c=='! ')state=5; elseif(c=='>')state=6; elseif(c=='<')state=7; elseif(c=='=')state=8; elseif(c=='.')state=17; elseif(c=='~')state=18; elseif(c=='%')state=19; elseif(c=='^')state=20; elseif(((int)c)==10){ state=9;//输入为回车 error_text.append("Line"+line+"\n\n"); }elseif(isLetter(c)){ state=10; begin=i; } elseif(isDigit(c)){ begin=i; state=11; }elseif(c=='#')state=12; elseif(c=='&')state=14; elseif(c=='|')state=15; elseif(c=='"')state=16; else{ err++; Stringa=end_text.getText(); a+="错误: line: "+line+"row: "+row+"error: '"+c+"'Undefinedcharacter! \n"; end_text.setText(a); error_text.append("错误: line: "+line+"row: "+row+"error: '"+c+"'Undefinedcharacter! \n"); } break; case1: //标志符是+ if(c=='+'){ state=0; error_text.append("\t运算符\t\t401"+"\t++"+'\n'); }elseif(c=='='){ state=0; error_text.append("\t运算符\t\t402"+"\t+="+'\n'); }else{ state=0; if(isDigit(content.charAt(i-2))) error_text.append("\t数值\t"+"\t200"+ content.substring(begin,i-1)+'\n'); error_text.append("\t运算符\t\t403"+"\t+"+'\n'); i--; row--; } break; case2: //标志符是- if(c=='-') error_text.append("\t运算符\t\t404"+"\t--"+'\n'); elseif(c=='=') error_text.append("\t运算符\t\t405"+"\t-="+'\n'); elseif(c=='>') error_text.append("\t运算符\t\t423"+"\t->"+'\n'); else{ error_text.append("\t运算符\t\t406"+"\t-"+'\n'); i--; row--; } state=0; break; case3: //标志符是* if(c=='=') error_text.append("\t运算符\t\t407"+"\t*="+'\n'); else{ error_text.append("\t运算符\t\t408"+"\t*"+'\n'); i--; row--; } state=0; break; case4: //标志符是/ if(c=='/'){ while((c)! ='\n'){ c=content.charAt(i); i++; } state=0; error_text.append("\t注释部分\t\t//\n"); }elseif(c=='='){ state=0; error_text.append("\t运算符\t\t409"+"\t/="+'\n'); }else{ state=0; error_text.append("\t运算符\t\t410"+"\t/"+'\n'); i--; row--; } //state=0; break; case5: //标志符是! if(c=='='){ error_text.append("\t运算符\t\t411"+"\t! ="+'\n'); state=0; }else{ state=0; i--; row--; error_text.append("\t运算符\t\t412"+"\t! "+'\n'); } break; case6: //标志符是> if(c=='='){ error_text.append("\t运算符\t\t413"+"\t>="+'\n'); state=0; } if(c=='>'){ error_text.append("\t运算符\t\t426"+"\t>>"+'\n'); state=0; }else{ state=0; i--; row--; error_text.append("\t运算符\t\t414"+"\t>"+'\n'); } //state=0; break; case7: //标志符是< if(c=='='){ error_text.append("\t运算符\t\t415"+"\t<="+'\n'); state=0; } if(c=='<'){ error_text.append("\t运算符\t\t427"+"\t<<"+'\n'); state=0; }else{ state=0; i--; row--; error_text.append("\t运算符\t\t416"+"\t<"+'\n'); } break; case8: //标志符是= if(c=='='){ error_text.append("\t运算符\t\t417"+"\t=="+'\n'); state=0; }else{ state=0; i--; row--; error_text.append("\t运算符\t\t418"+"\t="+'\n'); } break; case9: //标志符是回车 state=0; i--; row=1; line++; break; case10: //标志符是字母 if(isLetter(c)||isDigit(c)){ state=10; }else{ end=i; Stringid=content.substring(begin,end); if(isKey(id)! =0){ intt=isKey(id); error_text.append("\t关键字\t\t"+t+id+'\n'); }else error_text.append("\t标志符\t"+"\t100"+id+'\n'); i--; row--; state=0; } //state=0; break; case11: //标志符是数字 if(c=='e'||c=='E') state=13; elseif(isDigit(c)||c=='.'){ //省略跳过,i加一操作 }else{ if(isLetter(c)){ err++; Stringb=end_text.getText(); b+="错误: line"+line+"row"+row+"数字格式错误或者标志符错误\n"; end_text.setText(b); error_text.append("错误: line"+line+"row"+row+"数字格式错误或者标志符错误\n"); } inttemp=i; i=find(i,content); row+=(i-temp); state=0; } break; case12: //标志符是# Stringid=""; while(c! ='<'){ id+=c; i++; c=content.charAt(i); } if(id.trim().equals("include")){ while(c! ='>'&&(c! ='\n')){ i++; c=content.charAt(i); } if(c=='>') error_text.append("\t头文件引入\n"); }else{ err++; Stringd=end_text.getText(); d+="错误: "+"line
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 报告 词法 分析器