编译原理实验三-自下而上语法分析及语义分析.docx
电力学院
编译原理
课程实验报告
实验名称:实验三自下而上语法分析及语义分析院系:计算机科学与技术学院
专业年级:
学生:学号:
指导老师:
实验日期:
实验三自上而下的语法分析
一、实验目的:
通过本实验掌握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
五、处理程序例和处理结果例
示例1:20133191*(20133191+3191)+ 3191#
六、源代码
【cifa.h】
//cifa.h
#include
using namespace std;
//单词结构定义
struct WordType{
int code;
string pro;
};
//函数声明
WordType get_w();
void getch();
void getBC();
bool isLetter();
bool isDigit();
void retract();
int Reserve(string str); string concat(string str); 【Table.action.h】
//table_action.h
class Table_action
{
int row_num,line_num;
int lineName[8];
string tableData[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(int m=0;m for(int n=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][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[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][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"; } string getCell(int rowN,int lineN) { int row=rowN; int line=getLineNumber(lineN); if(row>=0&&row else return""; } int getLineNumber(int lineN) { for(int i=0;i if(lineName[i]==lineN) return i; return -1; } }; 【Table_go.h】 //table_go.h class Table_go { int row_num,line_num;//行数、列数 string lineName[3]; int tableData[16][3]; public: Table_go(){ row_num=16; line_num=3; lineName[0]="E"; lineName[1]="T"; lineName[2]="F"; for(int m=0;m for(int n=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; } int getCell(int rowN,string lineNa) { int row=rowN; int line=getLineNumber(lineNa); if(row>=0&&row else return -1; } int getLineNumber(string lineNa) { for(int i=0;i if(lineName[i]==lineNa) return i; return -1; } }; 【Stack_num.h】 class Stack_num { int i; //栈顶标记 int *data; //栈结构public: Stack_num() //构造函数 { data=new int[100]; i=-1; } int push(int m) //进栈操作 { i++; data[i]=m; return i; } int pop() //出栈操作 { i--; return data[i+1]; } int getTop() //返回栈顶 { return data[i]; } ~Stack_num() //析构函数 { delete []data; } int topNumber() { return i; } void outStack() { for(int m=0;m<=i;m++) cout< } }; 【Stack_str.h】 class Stack_str { int i; //栈顶标记 string *data; //栈结构public: Stack_str() //构造函数 { data=new string[50]; i=-1; } int push(string m) //进栈操作{ i++; data[i]=m; return i; } int pop() //出栈操作 { data[i]=""; i--; return i; } string getTop() //返回栈顶{ return data[i]; } ~Stack_str() //析构函数 { delete []data; } int topNumber() { return i; } void outStack() { for(int m=0;m<=i;m++) cout< } }; 【cifa.cpp】 //cifa.cpp #include #include #include"cifa.h" using namespace std; //关键字表和对应的编码 string codestring[10]={"main","int","if","then","else","return","void","cout","endl"}; int codebook[10]={26,21,22,23,24,25,27,28,29}; //全局变量 char ch; int flag=0; /*//主函数 int main() { WordType word; cout<<"请输入源程序序列:"; word=get_w(); while(word.pro!="#")//#为自己设置的结束标志 { cout<<"("< word=get_w(); }; return 0; }*/ WordType get_w() { string str=""; int code; WordType wordtmp; 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;}//是关键字} else if(isDigit()){ //以数字开头 while(isDigit()){ str=concat(str); getch(); } retract(); wordtmp.code=30; wordtmp.pro=str; } else if(ch=='(') {wordtmp.code=1;wordtmp.pro="(";} else if(ch==')') {wordtmp.code=2;wordtmp.pro=")";} else if(ch=='{') {wordtmp.code=3;wordtmp.pro="{";} else if(ch=='}') {wordtmp.code=4;wordtmp.pro="}";} else if(ch==';') {wordtmp.code=5;wordtmp.pro=";";} else if(ch=='=') {wordtmp.code=6;wordtmp.pro="=";} else if(ch=='+') {wordtmp.code=7;wordtmp.pro="+";} else if(ch=='*') {wordtmp.code=8;wordtmp.pro="*";} else if(ch=='>') {wordtmp.code=9;wordtmp.pro=">";} else if(ch=='<') {wordtmp.code=10;wordtmp.pro="<";} else if(ch==',') {wordtmp.code=11;wordtmp.pro=",";} else if(ch=='\'') {wordtmp.code=12;wordtmp.pro="\'";} else if(ch=='-') {wordtmp.code=13;wordtmp.pro="-";} else if(ch=='/') {wordtmp.code=14;wordtmp.pro="/";} else if(ch=='#') {wordtmp.code=15;wordtmp.pro="#";} else if(ch=='|') {wordtmp.code=16;wordtmp.pro="|";} else {wordtmp.code=100;wordtmp.pro=ch;} } void getch(){ if(flag==0) //没有回退的字符 ch=getchar(); else //有回退字符,用回退字符,并设置标志flag=0; } void getBC(){ while(ch==' '||ch=='\t'||ch=='\n') ch=getchar(); } bool isLetter(){ if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') return true; else return false; } bool isDigit(){ if(ch>='0'&&ch<='9') return true; else