编译原理实验二语法分析器的设计说明书.docx
- 文档编号:6430528
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:13
- 大小:98.88KB
编译原理实验二语法分析器的设计说明书.docx
《编译原理实验二语法分析器的设计说明书.docx》由会员分享,可在线阅读,更多相关《编译原理实验二语法分析器的设计说明书.docx(13页珍藏版)》请在冰豆网上搜索。
编译原理实验二语法分析器的设计说明书
集美大学计算机工程学院实验报告
课程名称:
编译原理
班级:
指导教师:
姓名:
实验项目编号:
实验二
学号:
实验项目名称:
语法分析器的设计
实验成绩:
一、实验目的
通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。
使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练掌握开发应用程序的基本方法。
二、实验内容
◆根据某一文法编制调试LL
(1)分析程序,以便对任意输入的符号串进行分析。
◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。
◆分析法的功能是利用LL
(1)控制程序根据显示栈栈顶内容、向前看符号以及LL
(1)分析表,对输入符号串自上而下的分析过程。
三、实验要求
1、编程时注意编程风格:
空行的使用、注释的使用、缩进的使用等。
2、如果遇到错误的表达式,应输出错误提示信息。
四、实验设计方案
1、设计思想
(1)、LL
(1)文法的定义
LL
(1)分析法属于确定的自顶向下分析方法。
LL
(1)的含义是:
第一个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将使用最左推导,1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推导。
LL
(1)文法的判别需要依次计算FIRST集、FOLLOW集和SELLECT集,然后判断是否为LL
(1)文法,最后再进行句子分析。
需要预测分析器对所给句型进行识别。
即在LL
(1)分析法中,每当在符号栈的栈顶出现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当出现终结符时,判断其与剩余输入串的第一个字符是否匹配,如果匹配,则继续分析,否则报错。
LL
(1)分析方法要求文法满足如下条件:
对于任一非终极符A的两个不同产生式A,A,都要满足下面条件:
SELECT(A)∩SELECT(A)=
(2)、预测分析表构造
LL
(1)分析表的作用是对当前非终极符和输入符号确定应该选择用哪个产生式进行推导。
它的行对应文法的非终极符,列对应终极符,表中的值有两种:
一是产生式的右部的字符串,一是null。
若用M表示LL
(1)分析表,则M可表示如下:
M:
VN×VTP∪{Error}
M(A,t)=Aα,当tselect(Aα),否则
M(A,t)=Error
其中P表示所有产生式的集合。
(3)、语法分析程序构造
LL
(1)分析中X为符号栈栈顶元素,a为输入流当前字符,E为给定测试数据的开始符号,#为句子括号即输入串的括号。
分析表用一个二位数组M表示,数组元素M[A,a]中的下标A表示非终结符,a为终结符或句子括号‘#’,二维数组中存放的是一条关于A的产生式,表明当非终结符A向下推导时,面临输入符a时,所采用的候选产生式,当元素内容无产生式时,则表明用A的左部向下推导时出现了不该出现的符号,因此元素内容转向出错处理的信息。
LL
(1)分析过程主要包括以下四个动作:
替换:
当XVN时选相应产生式的右部去替换X。
此时X出栈,逆序入栈。
匹配:
当XVT时它与a进行匹配,其结果可能成功,也可能失败,如果成功则符号栈中将X退栈并将输入流指针向前移动一位,否则报错。
接受:
当格局为(#,空#)时报告分析成功。
报错:
出错后,停止分析。
并给出相应的错误提示信息。
2.程序流程图:
3、实验程序
(1)分析栈类:
publicclassstack{
privatechars[];
privateinttop;
publicstack(){
s=newchar[200];
s[0]='#';
top=0;
}
chargetTop(){
returns[top];
}
voidpush(Stringstr){
for(inti=str.length()-1;i>=0;i--){
s[++top]=str.charAt(i);
}
}
voidclear(){
top=0;
}
charpop(){
if(top!
=0){
top--;
}
returns[top];
}
publicStringtoString(){
Stringtmp="";
for(inti=0;i<=top;i++){
tmp+=s[i];
}
returntmp;
}
}
(2)语法分析器类:
publicclassanlysis{
//分析表
privateStringtab[][]={{"$","+","-","*","/","(",")","i","#"},
{"E","$","$","$","$","TG","$","TG","$"},
{"G","+TG","-TG","$","$","$","ε","$","ε"},
{"T","$","$","$","$","FS","$","FS","$"},
{"S","ε","ε","*FS","/FS","$","ε","$","ε"},
{"F","$","$","$","$","(E)","$","i","$"}};
privateStringinput;//input中存放输入的表达式
privateStringBuffertempBuffer;//存放要输出的字符串
privateintptr,row,col,step;//指针,预测表中的行,列,当前步骤
privatebooleansymbol;
privatestackstack;
publicanlysis(){
stack=newstack();
tempBuffer=newStringBuffer();
symbol=true;
input="";
row=1;
ptr=0;
step=1;
}
//////////////////////////////////methods./////////////////////////////////
publicintcolumn(charc){//判断预测表中的列
switch(c){
case'+':
return1;
case'-':
return2;
case'*':
return3;
case'/':
return4;
case'(':
return5;
case')':
return6;
case'i':
return7;
case'#':
return8;
default:
return-1;
}
}
publicintline(charc){//判定预测表中的行
switch(c){
case'E':
return1;
case'G':
return2;
case'T':
return3;
case'S':
return4;
case'F':
return5;
default:
return-1;
}
}
publicvoidpri(Stringstr){
tempBuffer.append(String.format("%-8d%-20s%-20s%-20s\r\n",step,stack
.toString(),input.substring(ptr),str));
step++;
}
publicvoidanalyse(){
stack.push(tab[row][0]);//预测表中的第一个元素‘E’
pri("初始化");
Stringtmp;
charctmp;//栈顶元素
while(!
(input.charAt(ptr)=='#'&&stack.getTop()=='#')){
ctmp=stack.getTop();
if(input.charAt(ptr)==ctmp){//与栈顶元素比较
stack.pop();
ptr++;
pri(""+ctmp+"匹配");
continue;
}
col=column(input.charAt(ptr));
if(col==-1){
symbol=false;
pri("未定义的字符");
ptr++;
continue;
}
row=line(ctmp);
if(row==-1){
symbol=false;
pri("出错");
stack.pop();
if(input.charAt(ptr)!
='#'){
ptr++;
}
continue;
}
tmp=tab[row][col];
if(tmp.charAt(0)=='$'){
symbol=false;
pri("出错");
stack.pop();
if(input.charAt(ptr)!
='#'){
ptr++;
}
}elseif(tmp.charAt(0)=='ε'){
stack.pop();
pri(""+ctmp+"->"+'ε');
}else{
stack.pop();
stack.push(tmp);
pri(""+ctmp+"->"+tmp);
}
}
}
publicStringwork(Stringts){
input=ts;
input=input.trim()+'#';
symbol=true;
stack.clear();
tempBuffer.append("\r\n步骤分析栈剩余输入栈所用产生式\r\n");
analyse();
if(symbol){
tempBuffer.append("\r是正确的符号串\r");
returntempBuffer.toString();
}else{
tempBuffer.append("\r不是正确的符号串\r");
returntempBuffer.toString();
}
}
////////////////////////////////////getsandsets////////////////////////////////
publicStringBuffergetTempBuffer(){
returntempBuffer;
}
publicvoidsetTempBuffer(StringBuffertempBuffer){
this.tempBuffer=tempBuffer;
}
publicstackgetStack(){
returnstack;
}
publicvoidsetStack(stackstack){
this.stack=stack;
}
publicString[][]getTab(){
returntab;
}
publicvoidsetTab(String[][]tab){
this.tab=tab;
}
publicStringgetInput(){
returninput;
}
publicvoidsetInput(Stringns){
this.input=ns;
}
publicintgetPtr(){
returnptr;
}
publicvoidsetPtr(intptr){
this.ptr=ptr;
}
publicintgetRow(){
returnrow;
}
publicvoidsetRow(introw){
this.row=row;
}
publicintgetCol(){
returncol;
}
publicvoidsetCol(intcol){
this.col=col;
}
publicintgetStep(){
returnstep;
}
publicvoidsetStep(intstep){
this.step=step;
}
publicbooleanisBoo(){
returnsymbol;
}
publicvoidsetBoo(booleanboo){
this.symbol=boo;
}
}
(3)WINDOW窗体类:
importjava.awt.BorderLayout;
importjava.awt.GridLayout;
importjava.awt.Panel;
importjavax.swing.JFrame;
importjavax.swing.JScrollPane;
publicclassguiextendsjavax.swing.JFrame{
/**Createsnewformgui*/
privatejavax.swing.JButtonjButton1;
privatejavax.swing.JLabeljLabel1;
privatejavax.swing.JLabeljLabel2;
privatejavax.swing.JTextAreajTextArea1;
privatejavax.swing.JTextFieldjTextField1;
privatePanelp1=newPanel();
privatePanelp2=newPanel();
publicgui(){
initComponents();
}
privatevoidinitComponents(){
jLabel1=newjavax.swing.JLabel();
jTextField1=newjavax.swing.JTextField();
jLabel2=newjavax.swing.JLabel();
jTextArea1=newjavax.swing.JTextArea(20,30);
jButton1=newjavax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setText("本程序只能对由'+','-','*','/','(',')','i'构成的以'#'结尾的字符串进行分析。
请输入要翻译的表达式:
");
jLabel2.setText("分析结果:
");
jButton1.setText("分析");
jButton1.addActionListener(newjava.awt.event.ActionListener(){
publicvoidactionPerformed(java.awt.event.ActionEventevt){
jButton1ActionPerformed(evt);
}
});
finalGridLayoutgridLayout=newGridLayout(0,1);//创建表格布局管理器
gridLayout.setVgap(0);//设置组件之间垂直距离
gridLayout.setHgap(0);//设置组件之间平行距离
p1.setLayout(gridLayout);
p1.add(jLabel1);
p1.add(jTextField1);
p2.add(jLabel2);
p2.add(newJScrollPane(jTextArea1));
getContentPane().add(p1,BorderLayout.NORTH);
getContentPane().add(p2,BorderLayout.CENTER);
getContentPane().add(jButton1,BorderLayout.SOUTH);
setSize(600,500);
setLocation(400,100);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt){
anlysisans=newanlysis();
jTextArea1.setText(ans.work(jTextField1.getText()));
}
publicstaticvoidmain(Stringargs[]){
java.awt.EventQueue.invokeLater(newRunnable(){
publicvoidrun(){
newgui().setVisible(true);
}
});
}
}
五、实验结果
六、实验小结
1、本次实验主要运用java进行实验,通过完成预测分析法的语法分析程序,了解了预测分析法和递归子程序法的区别和联系,了解了语法分析的功能;
2、掌握了语法分析程序设计的原理和构造方法,掌握了开发应用程序的基本方法;
3、通过实验掌握了语法分析,能实现对普通字串的分析翻译。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 语法 分析器 设计 说明书