编译器_编译原理课程设计报告书

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

广西大学
编译原理课程设计
专业:计算机科学与技术
姓名:
课程:编译原理
指导教师:
目录
一.程序简介与分析---------------------------------------------------------1 二.程序适用围-----------------------------------------------------------1 三.词法分析---------------------------------------------------------------1 四.语法分析---------------------------------------------------------------3 五.语义分析和中间代码生成------------------------------------------------9 六.代码生成--------------------------------------------------------------11 七.流程图----------------------------------------------------------------12 八.实现------------------------------------------------------------------13 九.程序运行结果----------------------------------------------------------13 十.总结------------------------------------------------------------------18 十一.附录(源程序)--------------------------------------------------------19
简单的编译程序设计
一.程序简介与分析
本程序由四个部分组成:词法分析子程序,语法分析子程序,语义分析子程序,目标代码生成程序。

本程序输入一个叫haominjie.txt的c语言源程序,然后对它进行词法,语法,语义分析,并输出汇编代码。

词法分析输入的是c语言源程序,输出的3是具有独立语法意义的单词符号。

语法分析以词法分析产生的编码流为输入,按照SLR(1)分析方法进行语法分析,产生语法树,输出移进和归约的动作,如果源程序不符合文法,则有“语法分析出错”的提示。

语义分析阶段,在语法分析的同时,在归约的时候,给出相应的语义动作,最后输出中间代码四元式和新的符号表,如果有未声明的变量出现,则会提示出出错,并显示出此变量的名称。

代码生成阶段,将语义分析得到的中间代码四元式转化为汇编语言的目标代码并输出。

二.程序适用围
本程序的使用围为:整型常量,四则运算(为了简化问题,本程序只考虑加法运算和乘法运算)和布尔表达式以及相应的赋值语句,条件转移语句和循环语句。

三.词法分析
根据词法分析的需要,我将源程序中的单词符号分为:保留字,字母(标识符),
界符三类,统一用一表表示如下:
界符,保留字表
程序从源程序文件haominjie.txt中一次读入一个字符,并判断它是不是字母,界符,
保留字,空格,换行,结束符号或者非法字符。

流程图如下:
词法分析流程图
四.语法分析
○1.源程序中涉及的文法G[P]定义如下表:
○2.上述文法的每个非终结符的FIRST 集和FOLLOW集如下表:
FIRST 集 FOLLOW 集
P { id } { # }
L { id } { ; }
D { id } { ; }
E {(,id } { },;,+,),#}
T {(,id } { },;,+,),*,#}
F {(,id } { },;,+,),*,#}
B { id } {then,do,and}
M { id } { },;}
S {id,while,if} { },;}
N {id,while,if} { },;}
R { { } { # }
○3.文法G[P]的项目集部分如下:
0. P’→.P 1. P’→P.
2. P→.id()L;R
3. P→id.()L;R
4. P→id(.)L;R
5. P→id().L;R
6. P→id()L.;R
7. P→id()L;.R
8. P→id()L;R. 9. L→.L;D
10.L→L.;D 11. L→L;.D 12. L→L;D.
13.D→.id:int 14. D→id .:int 15. D→id: .int
16. D→id:int. 17.E→.E+T 18. E→E.+T
19. E→E+.T 20. E→E+T. 21. E→.T
22. E→T. 23. T→.T*F 24. T→T.*F
25. T→T*.F 26. T→T*F. 27. T→.F
28. T→F. 29. F→ (E) 30. F→ (.E)
31. F→ (E.) 32. F→ (E). 33. F→.id
34. F→id.
○4.再由项目集构造文法的DFA活前缀。

为了方便,省去了项目族集的每个状态的项目,直接在状态转换的箭头上标明终结符或非终结符。

对于有规约动作和接受的状态,将其特别标明。

文法G[P]的DFA图如下:
*
五.语义分析和中间代码生成
载语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(或语义规则描述的语义动作)进行翻译的办法称作语法制导翻译。

语法制导翻译
语法翻译生成的四元式如下:
六.代码生成
目标代码生成阶段的任务是把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。

这是编译的最后阶段,它的工作与硬件系统结构和指令含义有关,这个阶段的工作很复杂,涉及到硬件系统功能部件的运用、机器指令的选择、各种数据类型变量的存储空间分配以及寄存器和后缓寄存器的调度等。

本程序生成的目标代码与0x8086微处理器兼容。

下面列举几个简单的四元式与汇编代码的转化列子:
○1.(+,A,B,T)→
MOV R ,A ;
ADD R ,B ;
ST R , T
○2. ( *, A , B , T ) →
MOV R ,A ;
MUL R ,B ;
ST R , T
○3. ( J, _ , _ , L) →
JMP L
○4. ( J> , A , B , L ) →
MOV R , A
CMP R , B
JB L
○5. ( =,A , _ ,T ) →
LD R , A
ST R , T
本程序生成的目标代码如下:
七.程序流程图
编译程序流程图
八.实现
本程序运行的硬件环境为CPU 2GHZ ,存为4G .软件环境为windows 8.1 系统,Visual C++环境。

九.程序运行结果
1.输入源文件路径:
2.输出保留字
3.输出符号表的容
5.输出语法分析的结果(本程序采用自下而上的LR语法分析)
6.输出中间代码
7.输出目标代码
十.总结
通过本次实验,对编译程序各阶段有了更深刻更深入的了解,也纠正了自己在某些方面的的错误,丰富了自己关于编译原理方面的知识。

同时也培养了自己热爱思考,勤查资料的习惯。

由于水平本次实验涉及面并不是很全面,我只考虑了c语言的一个子集。

当然本程序的算法在某些地方也还存在一些缺陷。

十一.附录(源程序)
本程序输入的c源代码如下:
haominjie()
a:int;
b:int;
ccc:int;
d:int;
{
if ccc>b and ccc>a then a=b+a;
while ccc>d do a=d;
a=(b+ccc)*a+d
}
本程序的完整源代码如下:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
#include<cmath>
using namespace std;
struct token//词法 token结构体
{
int code;//编码
int num;//递增编号
token *next;
};
token *token_head,*token_tail;//token队列struct str//词法 string结构体
int num;//编号
string word;//字符串容
str *next;
};
str *string_head,*string_tail;//string队列struct ivan//语法产生式结构体
{
char left;//产生式的左部
string right;//产生式的右部
int len;//产生式右部的长度
};
ivan css[20];//语法 20个产生式
struct pank//语法 action表结构体
{
char sr;//移进或归约
int state;//转到的状态编号
};
pank action[46][18];//action表
int go_to[46][11];//语法 go_to表
struct ike//语法分析栈结构体,双链
{
ike *pre;
int num;//状态
int word;//符号编码
ike *next;
};
ike *stack_head,*stack_tail;//分析栈首尾指针struct L//语义四元式的数据结构
int k;
string op;//操作符
string op1;//操作数
string op2;//操作数
string result;//结果
L *next;//语义四元式向后指针
L *Ltrue;//回填true链向前指针
L *Lfalse;//回填false链向前指针
};
L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;/*四元式链,
true链,
false链*/ struct symb//语义输入时符号表
{
string word;//变量名称
int addr;//变量地址
symb *next;
};
symb *symb_head,*symb_tail;//语义符号链表
////////////////////////////////词法分析有关函数声明
void outdaima() ;
void scan();//按字符读取源文件
void cifa_main();//词法分析主程序
int judge(char ch);//判断输入字符的类型
void out1(char ch);//写入token.txt
void out3(char ch,string word);//写入string.txt
void input1(token *temp);//插入结点到队列token
void input3(str *temp);//插入结点到队列string
void output();//输出三个队列的容
void outfile();//输出三个队列的容到相应文件中
////////////////////////////////语法分析有关函数声明
void yufa_main();//语法分析主程序
void yufa_initialize();//初始化语法分析数据结构
int yufa_SLR1(int a);//语法分析主体部分
int ID1(int a);//给输入字符编号,转化成action表列编号string ID10(int i);//给输入字符反编号
int ID2(char ch);//给非终结状态编号,转化成go_to表列编号int ID20(char ch);//给非终结状态编号
char ID21(int j);//给非终结状态反编号
void add(ike *temp);//给ike分析栈链表增加一个结点
void del();//给ike分析栈链表删除一个结点
/////////////////////////////////语义分析相关函数的声明
void yuyi_main(int m);//语义分析主程序
void add_L_four(L *temp);//向四元式链中加一个结点
void add_L_true(L *temp);//向true链中加一个结点
void add_L_false(L *temp);//向false链中加一个结点
void add_symb(symb *temp);//向语义符号表链中加一个结点void output_yuyi();//输出中间代码四元式和最后符号表
string newop(int m);//把数字变成字符串
string id_numtoname(int num);//把编号转换成相应的变量名int lookup(string m);//变量声明检查
/////////////////////////////////全局变量的声明
FILE *fp;//文件指针
int wordcount;//标志符计数
int err;//标志词法分析结果正确或错误
int nl;//读取行数
int yuyi_linshi;//语义临时变量
string
E_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;//用于归约时名称传递和未声明变量的输出
int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;//用于记录一些特殊的字符位置信息
////////////////////////////////主程序开始
int main()
{
cout<<"************************"<<endl;
cout<<"* 说明: *"<<endl;
cout<<"* 第一部分:词法分析 *"<<endl;
cout<<"* 第二部分:语法分析 *"<<endl;
cout<<"* 第三部分:语义分析 *"<<endl;
cout<<"* 第四部分:目标代码生成 *"<<endl;
cout<<"************************"<<endl;
cifa_main();//词法
yufa_main();//语法
output_yuyi();//语义
outdaima(); //代码生成
cout<<endl;
system("pause");
return(0);
}
//////////////////////////////////词法分析子程序
void cifa_main()
{
token_head=new token;
token_head->next=NULL;
token_tail=new token;
token_tail->next=NULL;
string_head=new str;
string_head->next=NULL;
string_tail=new str;
string_tail->next=NULL;//初始化三个队列的首尾指针L_four_head=new L;
L_four_head->next=NULL;
L_four_tail=new L;
L_four_tail->k=0;
L_four_tail->next=NULL;
L_true_head=new L;
L_true_head->Ltrue=NULL;
L_false_head=new L;
L_false_head->Lfalse=NULL;
symb_head=new symb;
symb_head->next=NULL;
symb_tail=new symb;
symb_tail->next=NULL;
yuyi_linshi=-1;
id_num=0;
wordcount=0;//初始化字符计数器
err=0;//初始化词法分析错误标志
nl=1;//初始化读取行数
scan();
if(err==0)
{
char m;
output();
cout<<"词法分析正确完成!"<<endl<<endl<<"如果将结果保存到文件中请输入 y ,否则请输入其它字母:";
cin>>m;
cout<<endl;
if(m=='y')
{
outfile();
cout<<"结果成功保存在token.txt和sting.txt两个文件中,请打开查看"<<endl;
cout<<endl;
}
}
}
void scan()
{
cout<<endl;
system("pause");
cout<<endl;
char ch;
string word;
char document[50];
int flag=0;
cout<<"请输入源文件路径及名称:";
cin>>document;
cout<<endl;
cout<<"************************"<<endl;
cout<<"* 第一部分:词法分析 *"<<endl;
cout<<"************************"<<endl;
if((fp=fopen(document,"rt"))==NULL)
{
err=1;
cout<<"无法找到该文件!"<<endl;
return;
}
while(!feof(fp))
{
word="";
ch=fgetc(fp);
flag=judge(ch);
if(flag==1)
out1(ch);
else if(flag==3)
out3(ch,word);
else if(flag==4 || flag==5 ||flag==6)
continue;
else
{
cout<<nl<<"行 "<<"错误:非法字符! "<<ch<<endl;
err=1;
}
}
fclose(fp);
}
int judge(char ch)
{
int flag=0;
if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')')
flag=1;//界符
else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))
flag=3;//字母
else if(ch==' ')
flag=4;//空格
else if(feof(fp))
flag=5;//结束
else if(ch=='\n')
{
flag=6;//换行
nl++;
}
else
flag=0;//非法字符
return(flag);
}
void out1(char ch)
{
int id;
switch(ch)
{
case '=' : id=1;break;
case '+' : id=2;break;
case '*' : id=3;break;
case '>' : id=4;break;
case ':' : id=5;break;
case ';' : id=6;break;
case '{' : id=7;break;
case '}' : id=8;break;
case '(' : id=9;break;
case ')' : id=10;break;//界符编码default : id=0;
}
token *temp;
temp=new token;
temp->code=id;
temp->num=-1;
temp->next=NULL;
input1(temp);
return;
}
void out3(char ch,string word)
{
token *temp;
temp=new token;
temp->code=-1;
temp->num=-1;
temp->next=NULL;
str *temp1;
temp1=new str;
temp1->num=-1;
temp1->word="";
temp1->next=NULL;
int flag=0;
word=word+ch;
ch=fgetc(fp);
flag=judge(ch);
if(flag==1 || flag==4 || flag==5 || flag==6)
{
if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int")
{
if(word=="and")
temp->code=31;
else if(word=="if")
temp->code=32;
else if(word=="then")
temp->code=33;
else if(word=="while")
temp->code=35;
else if(word=="do")
temp->code=36;
else if(word=="int")
temp->code=37;//关键字编码
input1(temp);
if(flag==1)
out1(ch);
else if(flag==4 || flag==5 || flag==6)
return;
}
else if(flag==1)
{
wordcount++;
temp->code=25;
temp->num=wordcount;
input1(temp);
temp1->num=wordcount;
temp1->word=word;
input3(temp1);
out1(ch);
}
else if(flag==4 || flag==5 || flag==6)
{
wordcount++;
temp->code=25;
temp->num=wordcount;
input1(temp);
temp1->num=wordcount;
temp1->word=word;
input3(temp1);
}
return;
}
else if(flag==2 || flag==3)
out3(ch,word);//形成字符串
else
{
err=1;
cout<<nl<<"行 "<<"错误:非法字符! "<<ch<<endl;
return;
}
}
void input1(token *temp)
{
if(token_head->next == NULL)
{
token_head->next=temp;
token_tail->next=temp;
}
else
{
token_tail->next->next=temp;
token_tail->next=temp;
}
}
void input3(str *temp)
{
if(string_head->next == NULL)
{
string_head->next=temp;
string_tail->next=temp;
}
else
{
string_tail->next->next=temp;
string_tail->next=temp;
}
}
void output()
{
cout<<"token表容如下:"<<endl;
token *temp1;
temp1=new token;
temp1=token_head->next;
while(temp1!=NULL)
{
cout<<temp1->code;
if(temp1->num == -1)
{
cout<<endl;
}
else
{
cout<<" "<<temp1->num<<endl;
}
temp1=temp1->next;
}
cout<<"符号表容如下:"<<endl;
str *temp3;
temp3=new str;
temp3=string_head->next;
while(temp3!=NULL)
{
cout<<temp3->num<<" "<<temp3->word<<endl;
temp3=temp3->next;
}
}
void outfile()
{
ofstream fout1("token.txt");//写文件
ofstream fout3("string.txt");
token *temp1;
temp1=new token;
temp1=token_head->next;
while(temp1!=NULL)
{
fout1<<temp1->code;
if(temp1->num == -1)
fout1<<endl;
else
fout1<<" "<<temp1->num<<endl;
temp1=temp1->next;
}
str *temp3;
temp3=new str;
temp3=string_head->next;
while(temp3!=NULL)
{
fout3<<temp3->num<<" "<<temp3->word<<endl;
temp3=temp3->next;
}
}
/////////////////////////////////////////语法分析子程序
void yufa_main()
{
if(err==0)
{
system("pause");
cout<<endl;
cout<<"************************"<<endl;
cout<<"* 第二部分:语法分析 *"<<endl;
cout<<"************************"<<endl;
yufa_initialize();//初始化语法分析数据结构token *temp;
temp=new token;
temp=token_head->next;
int p,q;
p=0;
q=0;
cout<<"语法分析过程如下:"<<endl;
while(temp!=NULL)
{
int w;
w=ID1(temp->code);
p=yufa_SLR1(w);
if(p==1) break;
if(p==0)
temp=temp->next;
if(temp==NULL) q=1;
}//语法分析
if(q==1)
while(1)
{
p=yufa_SLR1(17);
if(p==3) break;
}//最后输入$来完成语法分析}
}
void yufa_initialize()
{
stack_head=new ike;
stack_tail=new ike;
stack_head->pre=NULL;
stack_head->next=stack_tail;
stack_head->num=0;
stack_head->word='!';
stack_tail->pre=stack_head;
stack_tail->next=NULL;//初始化栈分析链表css[0].left='Q';
css[0].right="P";
css[1].left='P';
css[1].right="id()L;R";
css[2].left='L';
css[2].right="L;D";
css[3].left='L';
css[3].right="D";
css[4].left='D';
css[4].right="id:int";
css[5].left='E';
css[5].right="E+T";
css[6].left='E';
css[6].right="T";
css[7].left='T';
css[7].right="T*F";
css[8].left='T';
css[8].right="F";
css[9].left='F';
css[9].right="(E)";
css[10].left='F';
css[10].right="id";
css[11].left='B';
css[11].right="B and B";
css[12].left='B';
css[12].right="id>id";
css[13].left='M';
css[13].right="id=E";
css[14].left='S';
css[14].right="if B then M"; css[15].left='S';
css[15].right="while B do M"; css[16].left='S';
css[16].right="M";
css[17].left='N';
css[17].right="N;S";
css[18].left='N';
css[18].right="S";
css[19].left='R';
css[19].right="{N}";
int i,j;
for(i=0;i<20;i++)
{
char *css_len;
css_len=&css[i].right[0];
css[i].len=strlen(css_len);
}
css[1].len=6;
css[4].len=3;
css[10].len=1;
css[11].len=3;
css[12].len=3;
css[13].len=3;
css[14].len=4;
css[15].len=4;//初始化产生式
for(i=0;i<46;i++)
{
for(j=0;j<18;j++)
action[i][j].sr='#';
}//初始化action表
for(i=0;i<46;i++)
{
for(j=0;j<11;j++)
go_to[i][j]=-1;
}//初始化go_to表
/****************************以下是给action表和go_to表赋初值************************/
action[0][0].sr='s';action[0][0].state=2;
action[1][17].sr='';//结束
action[2][1].sr='s';action[2][1].state=3;
action[3][2].sr='s';action[3][2].state=4;
action[4][0].sr='s';action[4][0].state=5;
action[5][4].sr='s';action[5][4].state=6;
action[6][11].sr='s';action[6][11].state=7;
action[7][3].sr='r';action[7][3].state=4; action[8][3].sr='r';action[8][3].state=3; action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18; action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31;
action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29; action[29][0].sr='s';action[29][0].state=14; action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10; action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8;
action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45; action[42][6].sr='s';action[42][6].state=43; action[43][0].sr='s';action[43][0].state=36; action[43][1].sr='s';action[43][1].state=41; action[44][2].sr='r';action[44][2].state=5; action[44][3].sr='r';action[44][3].state=5; action[44][5].sr='s';action[44][5].state=39; action[44][6].sr='r';action[44][6].state=5; action[44][10].sr='r';action[44][10].state=5; action[45][2].sr='r';action[45][2].state=9; action[45][3].sr='r';action[45][3].state=9; action[45][5].sr='r';action[45][5].state=9; action[45][6].sr='r';action[45][6].state=9; action[45][10].sr='r';action[45][10].state=9;
go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[1 0][2]=11;go_to[13][7]=22;go_to[13][8]=21;go_to[13][10]=17;
go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;g o_to[19][8]=20;go_to[23][6]=24;go_to[25][7]=26;go_to[27][6]=28;
go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;g o_to[41][4]=38;go_to[41][5]=37;go_to[43][4]=44;go_to[43][5]=37;
/****************************action表和go_to表赋初值完毕************************/
}
int ID1(int i)//按action表,给输入字符编号
{
int j;
j=-1;
if(i==25) {j=0;id_num++;}//设置变量名称标志
if(i==1) {j=8,id_left=id_num;}//设置产生试左边变量名称标志
if(i==2) j=6;
if(i==3) j=5;
if(i==4) j=7;
if(i==5) j=4;
if(i==6) j=3;
if(i==7) j=9;
if(i==8) j=10;
if(i==9) j=1;
if(i==10) j=2;
if(i==31) j=12;
if(i==32) j=13;
if(i==33) {j=14;id_then=L_four_tail->k+1;}//设置if语句中then位置标志
if(i==35) {j=15;id_while=L_four_tail->k+1;}//设置while语句中while 位置标志
if(i==36) {j=16;id_do=L_four_tail->k+1;}//设置while语句中do位置标志
if(i==37) j=11;
return(j);
}
string ID10(int i)//反编号输入字符
{
string ch;
if(i==0) ch="id";
if(i==1) ch="(";
if(i==2) ch=")";
if(i==3) ch=";";
if(i==4) ch=":";
if(i==5) ch="*";
if(i==6) ch="+";
if(i==7) ch=">";
if(i==8) ch="=";
if(i==9) ch="{";
if(i==10) ch="}";
if(i==11) ch="int";
if(i==12) ch="and";
if(i==13) ch="if";
if(i==14) ch="then";
if(i==15) ch="while";
if(i==16) ch="do";
if(i==17) ch="$";
return(ch);
}
int ID2(char ch)//按go_to表给非终结符编号{
int j;
j=-1;
if(ch=='P') j=0;
if(ch=='D') j=1;
if(ch=='R') j=2;
if(ch=='E') j=3;
if(ch=='T') j=4;
if(ch=='F') j=5;
if(ch=='B') j=6;
if(ch=='M') j=7;
if(ch=='S') j=8;
if(ch=='L') j=9;
if(ch=='N') j=10;
return(j);
}
int ID20(char ch)//给非终结符编号
{
int j;
j=-1;
if(ch=='P') j=100;
if(ch=='D') j=101;
if(ch=='R') j=102;
if(ch=='E') j=103;
if(ch=='T') j=104;
if(ch=='F') j=105;
if(ch=='B') j=106;
if(ch=='M') j=107;
if(ch=='S') j=108;
if(ch=='L') j=109;
if(ch=='N') j=1010;
return(j);
}
char ID21(int j)//反编号非终结符
{
char ch;
if(j==100 || j==0) ch='P';
if(j==101 || j==1) ch='D';
if(j==102 || j==2) ch='R';
if(j==103 || j==3) ch='E';
if(j==104 || j==4) ch='T';
if(j==105 || j==5) ch='F';
if(j==106 || j==6) ch='B';
if(j==107 || j==7) ch='M';
if(j==108 || j==8) ch='S';
if(j==109 || j==9) ch='L';
if(j==1010 || j==10) ch='N';
return(ch);
}
void add(ike *temp)//加一个结点
{
if(stack_head->next==stack_tail) {
temp->pre=stack_head;
temp->next=stack_tail;
stack_head->next=temp;
stack_tail->pre=temp;
}
else
{
temp->pre=stack_tail->pre;
temp->next=stack_tail;
stack_tail->pre->next=temp;
stack_tail->pre=temp;
}
}
void del()//删除一个结点
{
stack_tail->pre->pre->next=stack_tail;
stack_tail->pre=stack_tail->pre->pre;
}
int yufa_SLR1(int w)
{
/*cout<<"当前输入符号:"<<ID10(w)<<" ";*/
int i,flag=0,state_temp;//flag错误标志,0正常移进,1错误,2归约,3结束
char sr_temp;
sr_temp=action[stack_tail->pre->num][w].sr;//动作
state_temp=action[stack_tail->pre->num][w].state;//状态变化
if(sr_temp=='#')//错误动作
{
flag=1;
err=3;
cout<<"语法分析出错!"<<endl;
}
else if(sr_temp=='s')//移进动作
{
ike *temp;
temp=new ike;
temp->next=NULL;
temp->pre=NULL;
temp->word=w;
temp->num=state_temp;
add(temp);
cout/*<<"动作(移进):"*/<<sr_temp<<state_temp<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID10(stack_tail->pre->word)*/<<endl;
flag=0;
}
else if(sr_temp=='r')//归约动作
{
int p=ID2(css[state_temp].left);
int q=css[state_temp].len;
for(i=0;i<q;i++)
del();
ike *temp;
temp=new ike;
temp->next=NULL;
temp->pre=NULL;
temp->word=ID20(css[state_temp].left);
temp->num=go_to[stack_tail->pre->num][p];//查go_to表
add(temp);
cout/*<<"动作(归约):"*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态
转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;
flag=2;
yuyi_main(state_temp);//在产生树的同时进行语义分析}
else if(sr_temp=='')//结束动作
{
cout<<"END"/*<<"动作(归约):"<<sr_temp<<state_temp*/<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;
flag=3;
cout<<"语法分析正确完成!"<<endl;
}
else//其他意外情况
{
flag=1;
err=3;
cout<<"语法分析出错!"<<endl;
}
return(flag);
}
/////////////////////////////////////////语义分析子程序
void yuyi_main(int m)
{
L *temp;
int k;
k=1;
temp=new L;
temp->op=" ";
temp->op1=" ";
temp->op2=" ";
temp->result="";
temp->next=NULL;
temp->Ltrue=NULL;
temp->Lfalse=NULL;
if(m==4)//变量声明时加入符号表链
{
symb *Stemp;
Stemp=new symb;
id_name=id_numtoname(id_num);
Stemp->word=id_name;
Stemp->next=NULL;
add_symb(Stemp);
}
if(m==5)//归约E→E+T
{
temp->op="+";
temp->op1=E_name;
temp->op2=T_name;
yuyi_linshi++;//申请临时变量
E_name="t"+newop(yuyi_linshi);
temp->result=E_name;
add_L_four(temp);//加一个四元式结点}
if(m==6)//归约E→T。

相关文档
最新文档