编译原理实验三自下而上语法分析及语义分析x.docx
- 文档编号:10385674
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:25
- 大小:100.25KB
编译原理实验三自下而上语法分析及语义分析x.docx
《编译原理实验三自下而上语法分析及语义分析x.docx》由会员分享,可在线阅读,更多相关《编译原理实验三自下而上语法分析及语义分析x.docx(25页珍藏版)》请在冰点文库上搜索。
编译原理实验三自下而上语法分析及语义分析x
上海电力学院
编译原理
课程实验报告
实验名称:
实验三自下而上语法分析及语义分析
院 系:
计算机科学与技术学院
专业年级:
学生姓名:
学号:
指导老师:
实验日期:
实验三自上而下的语法分析
一、实验目的:
通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。
二、实验学时:
4学时。
三、实验内容
根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。
对于正确的表达式,给出表达式的值。
对于错误的表达式,给出出错位置。
四、实验方法
采用LR分析法。
首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。
属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。
接下来给出LR分析表。
然后程序的具体实现:
●LR分析表可用二维数组(或其他)实现。
●添加一个val栈作为语义分析实现的工具。
●编写总控程序,实现语法分析和语义分析的过程。
注:
对于整数的识别可以借助实验1。
五、文法定义
简单的表达式文法如下:
(1)E->E+T
(2)E->E-T
(3)E->T
(4)T->T*F
(5)T->T/F
(6)T->F
(7)F->(E)
(8)F->i
状态
ACTION(动作)
GOTO(转换)
i
+
-
*
/
(
)
#
E
T
F
0
S5
S4
1
2
3
1
S6
S12
acc
2
R3
R3
S7
S13
R3
R3
3
R6
R6
R6
R6
R6
R6
4
S5
S4
8
2
3
5
R8
R8
R8
R8
R8
R8
6
S5
S4
9
3
7
S5
S4
10
8
S6
R12
S11
9
R1
R1
S7
S13
R1
R1
10
R4
R4
R4
R4
R4
R4
11
R7
R7
R7
R7
R7
R7
12
S5
S4
14
3
13
S5
S4
15
14
R2
R2
S7
S13
R2
R2
15
R5
R5
R5
R5
R5
R5
五、处理程序例和处理结果例
示例1:
20133191*(20133191+3191)+3191#
六、源代码
【cifa.h】
//cifa.h
#include
usingnamespacestd;
//单词结构定义
structWordType{
intcode;
stringpro;
};
//函数声明
WordTypeget_w();
voidgetch();
voidgetBC();
boolisLetter();
boolisDigit();
voidretract();
intReserve(stringstr);
stringconcat(stringstr);
【Table.action.h】
//table_action.h
classTable_action
{
introw_num,line_num;
intlineName[8];
stringtableData[16][8];
public:
Table_action()
{
row_num=16;
line_num=8;
lineName[0]=30;
lineName[1]=7;
lineName[2]=13;
lineName[3]=8;
lineName[4]=14;
lineName[5]=1;
lineName[6]=2;
lineName[7]=15;
lineName[8]=0;
for(intm=0;m for(intn=0;n tableData[m][n]=""; tableData[0][0]="S5"; tableData[0][5]="S4"; tableData[1][1]="S6"; tableData[1][2]="S12"; tableData[1][7]="acc"; tableData[2][1]="R3"; tableData[2][2]="R3"; tableData[2][3]="S7"; tableData[2][4]="S13"; tableData[2][6]="R3"; tableData[2][7]="R3"; tableData[3][1]="R6"; tableData[3][2]="R6"; tableData[3][3]="R6"; tableData[3][4]="R6"; tableData[3][6]="R6"; tableData[3][7]="R6"; tableData[4][0]="S5"; tableData[4][5]="S4"; tableData[5][1]="R8"; tableData[5][2]="R8"; tableData[5][3]="R8"; tableData[5][4]="R8"; tableData[5][6]="R8"; tableData[5][7]="R8"; tableData[6][0]="S5"; tableData[6][5]="S4"; tableData[7][0]="S5"; tableData[7][5]="S4"; tableData[8][1]="S6"; tableData[8][2]="S12"; tableData[8][6]="S11"; tableData[9][1]="R1"; tableData[9][2]="R1"; tableData[9][3]="S7"; tableData[9][4]="S13"; tableData[9][6]="R1"; tableData[9][7]="R1"; tableData[10][1]="R4"; tableData[10][2]="R4"; tableData[10][3]="R4"; tableData[10][4]="R4"; tableData[10][6]="R4"; tableData[10][7]="R4"; tableData[11][1]="R7"; tableData[11][2]="R7"; tableData[11][3]="R7"; tableData[11][4]="R7"; tableData[11][6]="R7"; tableData[11][7]="R7"; tableData[12][0]="S5"; tableData[12][5]="S4"; tableData[13][0]="S5"; tableData[13][5]="S4"; tableData[14][1]="R2"; tableData[14][2]="R2"; tableData[14][3]="S7"; tableData[14][4]="S13"; tableData[14][6]="R2"; tableData[14][7]="R2"; tableData[15][1]="R5"; tableData[15][2]="R5"; tableData[15][3]="R5"; tableData[15][4]="R5"; tableData[15][5]="R5"; tableData[15][6]="R5"; tableData[15][7]="R5"; } stringgetCell(introwN,intlineN) { introw=rowN; intline=getLineNumber(lineN); if(row>=0&&row returntableData[row][line]; else return""; } intgetLineNumber(intlineN) { for(inti=0;i if(lineName[i]==lineN) returni; return-1; } }; 【Table_go.h】 //table_go.h classTable_go { introw_num,line_num;//行数、列数 stringlineName[3]; inttableData[16][3]; public: Table_go(){ row_num=16; line_num=3; lineName[0]="E"; lineName[1]="T"; lineName[2]="F"; for(intm=0;m for(intn=0;n tableData[m][n]=0; tableData[0][0]=1; tableData[0][1]=2; tableData[0][2]=3; tableData[4][0]=8; tableData[4][1]=2; tableData[4][2]=3; tableData[6][1]=9; tableData[6][2]=3; tableData[7][2]=10; tableData[12][1]=14; tableData[12][2]=3; tableData[13][2]=15; } intgetCell(introwN,stringlineNa) { introw=rowN; intline=getLineNumber(lineNa); if(row>=0&&row returntableData[row][line]; else return-1; } intgetLineNumber(stringlineNa) { for(inti=0;i if(lineName[i]==lineNa) returni; return-1; } }; 【Stack_num.h】 classStack_num { inti;//栈顶标记 int*data;//栈结构 public: Stack_num()//构造函数 { data=newint[100]; i=-1; } intpush(intm)//进栈操作 { i++; data[i]=m; returni; } intpop()//出栈操作 { i--; returndata[i+1]; } intgetTop()//返回栈顶 { returndata[i]; } ~Stack_num()//析构函数 { delete[]data; } inttopNumber() { returni; } voidoutStack() { for(intm=0;m<=i;m++) cout< } }; 【Stack_str.h】 classStack_str { inti;//栈顶标记 string*data;//栈结构 public: Stack_str()//构造函数 { data=newstring[50]; i=-1; } intpush(stringm)//进栈操作 { i++; data[i]=m; returni; } intpop()//出栈操作 { data[i]=""; i--; returni; } stringgetTop()//返回栈顶 { returndata[i]; } ~Stack_str()//析构函数 { delete[]data; } inttopNumber() { returni; } voidoutStack() { for(intm=0;m<=i;m++) cout< } }; 【cifa.cpp】 //cifa.cpp #include #include #include"cifa.h" usingnamespacestd; //关键字表和对应的编码 stringcodestring[10]={"main","int","if","then","else","return","void","cout","endl"}; intcodebook[10]={26,21,22,23,24,25,27,28,29}; //全局变量 charch; intflag=0; /*//主函数 intmain() { WordTypeword; cout<<"请输入源程序序列: "; word=get_w(); while(word.pro! ="#")//#为自己设置的结束标志 { cout<<"("< word=get_w(); }; return0; }*/ WordTypeget_w() { stringstr=""; intcode; WordTypewordtmp; getch();//读一个字符 getBC();//去掉空白符 if(isLetter()){//以字母开头 while(isLetter()||isDigit()){ str=concat(str); getch(); } retract(); code=Reserve(str); if(code==-1){wordtmp.code=0;wordtmp.pro=str;}//不是关键字 else{wordtmp.code=code;wordtmp.pro=str;}//是关键字 } elseif(isDigit()){//以数字开头 while(isDigit()){ str=concat(str); getch(); } retract(); wordtmp.code=30; wordtmp.pro=str; } elseif(ch=='('){wordtmp.code=1;wordtmp.pro="(";} elseif(ch==')'){wordtmp.code=2;wordtmp.pro=")";} elseif(ch=='{'){wordtmp.code=3;wordtmp.pro="{";} elseif(ch=='}'){wordtmp.code=4;wordtmp.pro="}";} elseif(ch==';'){wordtmp.code=5;wordtmp.pro=";";} elseif(ch=='='){wordtmp.code=6;wordtmp.pro="=";} elseif(ch=='+'){wordtmp.code=7;wordtmp.pro="+";} elseif(ch=='*'){wordtmp.code=8;wordtmp.pro="*";} elseif(ch=='>'){wordtmp.code=9;wordtmp.pro=">";} elseif(ch=='<'){wordtmp.code=10;wordtmp.pro="<";} elseif(ch==','){wordtmp.code=11;wordtmp.pro=",";} elseif(ch=='\''){wordtmp.code=12;wordtmp.pro="\'";} elseif(ch=='-'){wordtmp.code=13;wordtmp.pro="-";} elseif(ch=='/'){wordtmp.code=14;wordtmp.pro="/";} elseif(ch=='#'){wordtmp.code=15;wordtmp.pro="#";} elseif(ch=='|'){wordtmp.code=16;wordtmp.pro="|";} else{wordtmp.code=100;wordtmp.pro=ch;} returnwordtmp; } voidgetch(){ if(flag==0)//没有回退的字符 ch=getchar(); else//有回退字符,用回退字符,并设置标志 flag=0; } voidgetBC(){ while(ch==''||ch=='\t'||ch=='\n') ch=getchar(); } boolisLetter(){ if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') returntrue; else returnfalse; } boolisDigit(){ if(ch>='0'&&ch<='9') returntrue; else returnfalse; } stringconcat(stringstr){ returnstr+ch; } voidretract(){ flag=1; } intReserve(stringstr){ inti; for(i=0;i<=8;i++){ if(codestring[i]==str)//是某个关键字,返回对应的编码 returncodebook[i]; } if(i==9)//不是关键字 return-1; } 【LR.cpp】 #include #include #include #include"cifa.h" #include"stack_num.h" #include"stack_str.h" #include"table_action.h" #include"table_go.h" usingnamespacestd; voidprocess(){ intstepNum=1; inttopStat; Stack_numstatusSTK;//状态栈 Stack_strsymbolSTK;//符号栈 Stack_numvalueSTK;//值栈 WordTypeword; Table_actionactionTAB;//行为表 Table_gogoTAB;//转向表 cout<<"请输入源程序,以#结束: "; word=get_w(); //总控程序初始化操作 symbolSTK.push("#"); statusSTK.push(0); valueSTK.push(0); cout<<"步骤\t状态栈\t符号栈\t值栈\t当前词\t动作\t转向"< //分析 while (1) { topStat=statusSTK.getTop();//当前状态栈顶 stringact=actionTAB.getCell(topStat,word.code);//根据状态栈顶和当前单词查到的动作 //输出 cout< statusSTK.outStack();cout<<"\t"; symbolSTK.outStack();cout<<"\t"; valueSTK.outStack();cout<<"\t"; cout< //行为为“acc”,且当前处理的单词为#,且状态栈里就两个状态 //说明正常分析结束 if(act=="acc"&&word.pro=="#"&&statusSTK.topNumber()==1) { cout< cout<<"分析成功! "< cout<<"结果为: "< return; } //读到act表里标记为错误的单元格 elseif(act=="") { cout< "< cout<<"错误的位置为单词"< "; return; } //移进动作 elseif(act[0]=='S') { intnewstat=atoi(act.substr (1).c_str()); statu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 自下而上 语法分析 语义 分析