实验一词法分析.docx
- 文档编号:5438740
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:22
- 大小:41.94KB
实验一词法分析.docx
《实验一词法分析.docx》由会员分享,可在线阅读,更多相关《实验一词法分析.docx(22页珍藏版)》请在冰豆网上搜索。
实验一词法分析
实验一词法分析
一、实验目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)(不限语言,该试验占平时分10分)
二、实验预习提示
1、词法分析器的功能和输出格式
词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是一类符号一种别码的方式。
2、单词的BNF表示
<标识符>-><字母><字母数字串>
<字母数字串>-><字母><字母数字串>|<数字><字母数字串>|
<下划线><字母数字串>|ε
<无符号整数>-><数字><数字串>
<数字串>-><数字><数字串>|ε
<加法运算符>->+
<减法运算符>->-
<大于关系运算符>->>
<大于等于关系运算符>->>=
3、“超前搜索”方法
词法分析时,常常会用到超前搜索方法。
如当前待分析字符串为“a>+”,当前字符为’>’,此时,分析器倒底是将其分析为大于关系运算符还是大于等于关系运算符呢?
显然,只有知道下一个字符是什么才能下结论。
于是分析器读入下一个字符’+’,这时可知应将’>’解释为大于运算符。
但此时,超前读了一个字符’+’,所以要回退一个字符,词法分析器才能正常运行。
在分析标识符,无符号整数等时也有类似情况。
4、模块结构
三、实验过程和指导:
(一)准备:
1.阅读课本有关章节,明确语言的语法,写出基本保留字、标识符、常数、运算符、分隔符和程序例。
2.初步编制好程序。
3.准备好多组测试数据。
(二)上课上机:
将源代码拷贝到机上调试,发现错误,再修改完善。
第二次上机调试通过。
(三)程序要求:
程序输入/输出示例:
(2,”main”)
(5,”(“)
(5,”)“)
(5,”{“)
(1,”int”)
(2,”a”)
(5,”,”)
(2,”b”)
(5,”;”)
(2,”a”)
(4,”=”)
(3,”10”)
(5,”;”)
(2,”b”)
(4,”=”)
(2,”a”)
(4,”+”)
(3,”20”)
(5,”;”)
(5,”}“)
如源程序为C语言。
输入如下一段:
main()
{
inta,b;
a=10;
b=a+20;
}
要求输出如右图。
要求:
识别保留字:
if、int、for、while、do、return、break、continue;
单词种别码为1。
其他的都识别为标识符;单词种别码为2。
常数为无符号整形数;单词种别码为3。
运算符包括:
+、-、*、/、=、>、<、>=、<=、!
=;
单词种别码为4。
分隔符包括:
、;、{、}、(、);单词种别码为5。
以上为参考,具体可自行增删。
(四)程序思路(仅供参考):
这里以开始定义的C语言子集的源程序作为词法分析程序的输入数据。
在词法分析中,自文件头开始扫描源程序字符,一旦发现符合“单词”定义的源程序字符串时,将它翻译成固定长度的单词内部表示,并查填适当的信息表。
经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词串(源程序的内部表示),并产生两个表格:
常数表和标识符表,它们分别包含了源程序中的所有常数和所有标识符。
0.定义部分:
定义常量、变量、数据结构。
1.初始化:
从文件将源程序全部输入到字符缓冲区中。
2.取单词前:
去掉多余空白。
3.取单词后:
去掉多余空白(可选,看着办)。
4.取单词:
利用实验一的成果读出单词的每一个字符,组成单词,分析类型。
(关键是如何判断取单词结束?
取到的单词是什么类型的单词?
)
5.显示结果。
(五)练习该实验的目的和思路:
程序开始变得复杂起来,可能是大家目前编过的程序中最复杂的,但相对于以后的程序来说还是简单的。
因此要认真把握这个过渡期的练习。
本实验和以后的实验相关。
通过练习,掌握对字符进行灵活处理的方法。
(六)为了能设计好程序,注意以下事情:
1.模块设计:
将程序分成合理的多个模块(函数),每个模块做具体的同一事情。
2.写出(画出)设计方案:
模块关系简图、流程图、全局变量、函数接口等。
3.编程时注意编程风格:
空行的使用、注释的使用、缩进的使用等。
四、上交:
1.程序源代码和实验文档(电子版提交到ftp);
2.已经测试通过的测试数据3组;
3.实验报告(纸质):
实验名称
实验目的和要求
(一)实验内容
(1)功能描述:
该程序具有什么功能?
(2)程序结构描述:
函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。
(3)程序总体执行流程图
(二)实验过程记录:
出错次数、出错严重程度、解决办法摘要。
(三)实验总结:
你在编程过程中花时多少?
多少时间在纸上设计?
多少时间上机输入和调试?
多少时间在思考问题?
遇到了哪些难题?
你是怎么克服的?
你对你的程序的评价?
你的收获有哪些?
importjava.awt.*;
importjava.awt.event.*;
importjava.io.*;
importjavax.swing.*;
importjavax.swing.JOptionPane;
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...",FileDialog.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));
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();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验一 词法分析 实验 词法 分析