好文档 - 专业文书写作范文服务资料分享网站

编译原理实验三-自下而上语法分析及语义分析 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

状态 i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 S5 S5 S5 S5 S5 S5 + S6 R3 R6 R8 S6 R1 R4 R7 R2 R5 - S12 R3 R6 R8 R12 R1 R4 R7 R2 R5 ACTION(动作) GOTO(转换) * S7 R6 R8 S7 R4 R7 S7 R5 / S13 R6 R8 S13 R4 R7 S13 R5 ( S4 S4 S4 S4 S4 S4 ) R3 R6 R8 S11 R1 R4 R7 R2 R5 # acc R3 R6 R8 R1 R4 R7 R2 R5 E 1 8 T 2 2 9 14 F 3 3 3 10 3 15 . 可修编-

. - -

五、处理程序例和处理结果例

示例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

tableData[m][n]=\

tableData[0][0]=\ tableData[0][5]=\ tableData[1][1]=\ tableData[1][2]=\ tableData[1][7]=\

tableData[2][1]=\

. 可修编-

. - -

tableData[2][2]=\ tableData[2][3]=\ tableData[2][4]=\ tableData[2][6]=\ tableData[2][7]=\ tableData[3][1]=\ tableData[3][2]=\ tableData[3][3]=\ tableData[3][4]=\ tableData[3][6]=\ tableData[3][7]=\ tableData[4][0]=\ tableData[4][5]=\ tableData[5][1]=\ tableData[5][2]=\ tableData[5][3]=\ tableData[5][4]=\ tableData[5][6]=\ tableData[5][7]=\ tableData[6][0]=\ tableData[6][5]=\

tableData[7][0]=\

. 可修编-

. - -

tableData[7][5]=\ tableData[8][1]=\ tableData[8][2]=\ tableData[8][6]=\ tableData[9][1]=\ tableData[9][2]=\ tableData[9][3]=\ tableData[9][4]=\ tableData[9][6]=\ tableData[9][7]=\ tableData[10][1]=\ tableData[10][2]=\ tableData[10][3]=\ tableData[10][4]=\ tableData[10][6]=\ tableData[10][7]=\ tableData[11][1]=\ tableData[11][2]=\ tableData[11][3]=\ tableData[11][4]=\ tableData[11][6]=\

tableData[11][7]=\

. 可修编-

. - -

tableData[12][0]=\ tableData[12][5]=\ tableData[13][0]=\ tableData[13][5]=\ tableData[14][1]=\ tableData[14][2]=\ tableData[14][3]=\ tableData[14][4]=\ tableData[14][6]=\ tableData[14][7]=\ tableData[15][1]=\ tableData[15][2]=\ tableData[15][3]=\ tableData[15][4]=\ tableData[15][5]=\ tableData[15][6]=\

tableData[15][7]=\

}

string getCell(int rowN,int lineN) { int row=rowN;

int line=getLineNumber(lineN);

. 可修编-

. - -

if(row>=0&&row=0&&line<=line_num)

return tableData[row][line];

else

return\

}

int getLineNumber(int lineN) { for(int i=0;i

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]=\ lineName[1]=\

lineName[2]=\

for(int m=0;m

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

return tableData[row][line];

else

return -1;

}

int getLineNumber(string lineNa) { for(int i=0;i

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%using namespace std;

//关键字表和对应的编码

. 可修编-

. - -

string codestring[10]={\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;} . 可修编-

. - -

return wordtmp;

}

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

. 可修编-

. - -

return false;

}

string concat(string str){ return str+ch;

}

void retract(){ flag=1; }

int Reserve(string str){ int i;

for(i=0;i<=8;i++){ if(codestring[i]==str) //是某个关键字,返回对应的编码

return codebook[i];

}

if(i==9) //不是关键字

return -1;

}

【LR.cpp】 #include #include #include #include\

. 可修编-

. - -

#include\#include\#include\#include%using namespace std;

void process(){ int stepNum=1; int topStat;

Stack_num statusSTK; //状态栈

Stack_str symbolSTK; //符号栈

Stack_num valueSTK; //值栈

WordType word;

Table_action actionTAB; //行为表

Table_go goTAB; //转向表 cout<<\请输入源程序,以#结束:\ word=get_w();

//总控程序初始化操作

symbolSTK.push(\ statusSTK.push(0);

valueSTK.push(0);

. 可修编-

. - -

cout<<\步骤\\t状态栈\\t符号栈\\t值栈\\t当前词\\t动作\\t转向\//分析 while(1) {

topStat=statusSTK.getTop(); //当前状态栈顶

string act=actionTAB.getCell(topStat,word.code);//根据状态栈顶和当前单词

查到的动作

//输出

cout<

statusSTK.outStack(); cout<<\symbolSTK.outStack(); cout<<\valueSTK.outStack(); cout<<\cout<

//行为为“acc”,且当前处理的单词为#,且状态栈里就两个状态 //说明正常分析结束

if(act==\{

cout<

cout<<\分析成功!\

cout<<\结果为:\return;

. 可修编-

. - -

}

//读到act表里标记为错误的单元格 else if(act==\{ cout<

}

//移进动作 else if(act[0]=='S') { int newstat=atoi(act.substr(1).c_str()); statusSTK.push(newstat); symbolSTK.push(word.pro); if(word.code==30)//整数,压入其值

valueSTK.push(atoi(word.pro.c_str())); else //其他单词,压入0占位

valueSTK.push(0);

//输出 word=get_w(); cout<

}

. 可修编-

. - -

//规约动作 else if(act[0]=='R') { cout<

string sn=act.substr(1);//产生式编号 //根据规约使用的产生式更新各个栈 if(sn==\ { statusSTK.pop();statusSTK.pop();statusSTK.pop(); symbolSTK.pop();symbolSTK.pop();symbolSTK.pop(); symbolSTK.push(\ int right_digit=valueSTK.pop(); valueSTK.pop();

int left_digit=valueSTK.pop(); int new_value=left_digit+right_digit; valueSTK.push(new_value);

}

else if(sn==\ { statusSTK.pop();statusSTK.pop();statusSTK.pop(); symbolSTK.pop();symbolSTK.pop();symbolSTK.pop();

symbolSTK.push(\

. 可修编-

. - -

int right_digit=valueSTK.pop(); valueSTK.pop();

int left_digit=valueSTK.pop(); int new_value=left_digit-right_digit; valueSTK.push(new_value);

}

else if(sn==\ { statusSTK.pop();statusSTK.pop();statusSTK.pop(); symbolSTK.pop();symbolSTK.pop();symbolSTK.pop(); symbolSTK.push(\ int right_digit=valueSTK.pop(); valueSTK.pop();

int left_digit=valueSTK.pop(); int new_value=left_digit*right_digit; valueSTK.push(new_value);

}

else if(sn==\ { statusSTK.pop();statusSTK.pop();statusSTK.pop(); symbolSTK.pop();symbolSTK.pop();symbolSTK.pop();

symbolSTK.push(\

. 可修编-

. - -

int right_digit=valueSTK.pop(); valueSTK.pop();

int left_digit=valueSTK.pop(); int new_value=left_digit/right_digit; valueSTK.push(new_value);

}

else if(sn==\ { statusSTK.pop(); symbolSTK.pop(); symbolSTK.push(\

}

else if(sn==\ { statusSTK.pop(); symbolSTK.pop(); symbolSTK.push(\ }

else if(sn==\ { statusSTK.pop();statusSTK.pop();statusSTK.pop();

symbolSTK.pop();symbolSTK.pop();symbolSTK.pop(); . 可修编-

. - -

}

symbolSTK.push(\valueSTK.pop();

int digit_val=valueSTK.pop(); valueSTK.pop(); valueSTK.push(digit_val);

else if(sn==\{ } else { }

//实施go表中的动作

int next_status=goTAB.getCell(statusSTK.getTop(),symbolSTK.getTop()); statusSTK.push(next_status); //输出

cout<

cout<<\分析程序出错!\return;

statusSTK.pop(); symbolSTK.pop(); symbolSTK.push(\

. 可修编-

. - -

} else { cout<<\分析程序出错。\ return ;

}

} }

int main() { char ch; do { system(\ process();

cout<

cin>>ch;

}while(ch=='y'); return 0;

}

. 可修编-

8aqw80jfzv9vfqx3d4pq7px008twst015d3
领取福利

微信扫码领取福利

微信扫码分享