logo资料库

编译原理课设_(词法分析、自下而上语法分析程序、生成中间代码).doc

第1页 / 共46页
第2页 / 共46页
第3页 / 共46页
第4页 / 共46页
第5页 / 共46页
第6页 / 共46页
第7页 / 共46页
第8页 / 共46页
资料共46页,剩余部分请下载后查看
内容摘要
第1章 绪论
1.1、课程设计目的
1.2、课程设计意义
1.3、课程设计要求
1.4、课程设计内容
1.4.1、题目
1.4.2、内容
1.4.3、具体要求
1.4.4、程序设计提示
1.4.5、测试数据
1.4.6、程序扩展要求
第2章 程序总体设计
第3章 程序详细设计与实现
3.1、词法分析
3.2、语法分析
3.3、语义分析
3.4、程序实现结果图
图3-4 语义分析结果图
图3-5二元式
图3-6符号表
图3-7四元式
附录
#include
#include
using namespace std;
#define maxsize 50
#define max 30
ifstream infile;
char ch;
int m,n,kk=0,addr=0,t=1;
string get1;
string in[maxsize];
string ins[maxsize];
string s[4];
int count=0;
string v1[8]={"int","float",";",",","id","#","D","
string v2[13]={"#","id","=","num",";","+","*","(",
string E="",E1="",T="",T1="",F="";
int analysis_table1[10][8]={3,4,0,0,0,0,2,1,
0,0,0,0,0,100,0,0,
0,0,5,6,0,0,0,0,
0,0,0,0,7,0,0,0,
0,0,0,0,8,0,0,0,
0,0,0,0,0,-1,0,0,
0,0,0,0,9,0,0,0,
0,0,-2,-2,0,0,0,0,
0,0,-3,-3,0,0,0,0,
0,0,-4,-4,0,0,0,0};
int analysis_table2[17][13]={0,2,0,0,0,0,0,0,0,0,
100,0,0,0,0,0,0,0,0,
0,0,3,0,0,0,0,0,0,0,0,0,0,
0,9,0,8,0,0,0,7,0,6,0,4,5,
0,0,0,0,10,11,0,0,0,0,0,0,0,
0,0,0,0,-3,-3,12,0,-3,0,0,0,0,
0,0,0,0,-5,-5,-5,0,-5,0,0,0,0,
0,9,0,8,0,0,0,7,0,6,0,13,5,
0,0,0,0,-8,-8,-8,0,-8,0,0,0,0,
0,0,0,0,-7,-7,-7,0,-7,0,0,0,0,
-1,0,0,0,0,0,0,0,0,0,0,0,0,
0,9,0,8,0,0,0,7,0,6,0,0,14,
0,9,0,8,0,0,0,7,0,15,0,0,0,
0,0,0,0,0,11,0,0,16,0,0,0,0,
0,0,0,0,-2,-2,12,0,-2,0,0,0,0,
0,0,0,0,-4,-4,-4,0,-4,0,0,0,0,
0,0,0,0,-6,-6,-6,0,-6,0,0,0,0};
typedef struct //状态栈
{
int data[max];
int top;
}seqstack1;
typedef struct //符号栈
{
string data[max];
int top;
}seqstack2;
struct reserveedword//保留字表结构
{
string word;
char value;
}reserveedword1[maxsize];
struct identifer//标识符表结构
{
char identiname[15];
char identitype[15];
int address;
}identifer1[maxsize];
struct constant//常量表结构
{
string constantname;
string value;
int constantaddress;
}constant1[maxsize];
void Initscanner();
void Lexscan();
void Isalpha(char);
void Isnumber(char);
void Isother(char);
void Output(int ,int ,char *);
void Scanner();
void change(char c[],string str)
{
int len=str.length();
for(int num=0;num
c[num]=str[num];
c[len]='\0';
}
seqstack1 *init_seqstack1()
{
seqstack1 *s;
s=new seqstack1;
if(!s)
{
cout<<"空间不足!"<
return NULL;
}
else
{
s->top=-1;
return s;
}
}
int empty_seq1(seqstack1 *s)
{
if(s->top==-1)
return 1;
else
return 0;
}
int push_seq1(seqstack1 *s,int x)
{
if(s->top==max-1)
return 0;
else
{
s->top++;
s->data[s->top]=x;
return 1;
}
}
int pop_seq1(seqstack1 *s,int *x)
{
if(empty_seq1(s))
return 0;
else
{
*x=s->data[s->top];
s->top--;
return 1;
}
}
void top_seq1(seqstack1 *s,int &e)
{
if(empty_seq1(s))
cout<<"占空!";
else
e=s->data[s->top];
}
seqstack2 *init_seqstack2()
{
seqstack2 *s;
s=new seqstack2;
if(!s)
{
cout<<"空间不足!"<
return NULL;
}
else
{
s->top=-1;
return s;
}
}
int empty_seq2(seqstack2 *s)
{
if(s->top==-1)
return 1;
else
return 0;
}
int push_seq2(seqstack2 *s,string x)
{
if(s->top==max-1)
return 0;
else
{
s->top++;
s->data[s->top]=x;
return 1;
}
}
int pop_seq2(seqstack2 *s,string *x)
{
if(empty_seq2(s))
return 0;
else
{
*x=s->data[s->top];
s->top--;
return 1;
}
}
void out_seq1(seqstack1 *s)
{
for(int i=0;i<=s->top;i++)
printf("%d",s->data[i]);
}
void out_seq2(seqstack2 *s)
{
char ch[15];
for(int i=0;i<=s->top;i++)
{
change(ch,s->data[i]);
printf("%s",ch);
}
}
seqstack1 *s1=init_seqstack1();
seqstack2 *s2=init_seqstack2();
seqstack2 *s3=init_seqstack2();
void pop(int n)
{
int m;
string s;
for(int i=0;i
{
pop_seq1(s1,&m);
pop_seq2(s2,&s);
pop_seq2(s3,&s);
}
}
int screamp(char a[15],string b)
{
int i=0,j=0;
while(a[i]!='\0'&&b[i]!='\0')
{
if(a[i]==b[i])
{
i++;
j++;
}
else
return 0;
}
if(a[i]==b[i])
return 1;
else
return 0;
}
int screamp1(string a,string b)
{
int i=0,j=0;
while(a[i]!='\0'&&b[i]!='\0')
{
if(a[i]==b[i])
{
i++;
j++;
}
else
return 0;
}
if(a[i]==b[i])
return 1;
else
return 0;
}
void clear(seqstack1 *s1,seqstack2 *s2,seqstack2 *
{
int m;
string s;
while(!empty_seq1(s1))
{
pop_seq1(s1,&m);
pop_seq2(s2,&s);
pop_seq2(s3,&s);
}
}
void char_Table()
{
char str1[15],str2[15];
cout<<"\n生成的标识符表为:";
cout<<"\n\tname\ttype\tvalue\taddress";
for(int i=0;i
printf("\n%d\t%s\t%s",i,identifer1[i].identina
cout<<"\n生成的常数表为:";
cout<<"\n\tvalue\ttype\tname\taddress";
for(int j=0;j
{
change(str1,constant1[j].constantname);
change(str2,constant1[j].value);
printf("\n%d\t%s\t%s",j,str1,str2);
}
}
int judge(string m[],int i,string x)
{
for(int j=0;j
if(screamp1(x,m[j]))
return 1;
return 0;
}
int address(string m[],int i,string x)
{
for(int j=0;j
if(screamp1(x,m[j]))
return j;
}
void print(string s[])
{
cout<<"\n产生的四元式为"<
char ch[max];
for(int i=0;i
{
change(ch,s[i]);
printf("%s",ch);
cout<
}
cout<
}
void emit(string str1,string str2,string str3,stri
{
s[count]+="(";s[count]+=str1;s[count]+=",";
s[count]+=str2;s[count]+=",";s[count]+=str3;
s[count]+=",";s[count]+=str4;s[count]+=")";
count++;
}
string newtemp()
{
char s[2];
s[0]='T';
s[1]=t;
s[2]='\0';
t++;
return s;
}
void action1(int i,string s)
{
int pos,j;
j=address(v1,8,s);
pos=analysis_table1[i][j];
char str[15];
change(str,s);
out_seq1(s1);
printf("\t\t");out_seq2(s2);printf("\t\t");out_se
if(pos==100)
{
cout<<"分析成功!"<
cout<<"**************************************
}
else
printf("action[%d,%s]=S%d状态%d入栈\n",i,str,pos,po
push_seq1(s1,pos);
push_seq2(s2,s);
push_seq2(s3,"_");
get1=in[addr];
addr++;
}
void goto1(int i,string s)
{
int pos,j;
if(judge(v1,8,s))
j=address(v1,8,s);
pos=analysis_table1[i][j];
char str[15];
change(str,s);
printf("goto[%d,%s]=%d\n",i,str,pos);
push_seq1(s1,pos);
push_seq2(s2,s);
}
void slr1()
{
clear(s1,s2,s3);
char str1[15];
push_seq1(s1,0);
push_seq2(s2,"#");
push_seq2(s3,"_");
get1=in[addr];
addr++;
int top,j;
while(1)
{
j=address(v1,8,get1);
top_seq1(s1,top);
if(top==100)
{
addr--;
return;
}
j=analysis_table1[top][j];
if(j<0)
{
if(j==-1)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(2);
top_seq1(s1,top);
goto1(top,"S");
push_seq2(s3,"_");
}
else if(j==-2)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
change(str1,"int");
for(int k=0;k<15;k++)
identifer1[kk].identitype[k]=str
kk++;
pop(2);
top_seq1(s1,top);
goto1(top,"D");
push_seq2(s3,"_");
}
else if(j==-3)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
change(str1,"float");
for(int k=0;k<15;k++)
identifer1[kk].identitype[k]=st
kk++;
pop(2);
top_seq1(s1,top);
goto1(top,"D");
push_seq2(s3,"_");
}
else if(j==-4)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
for(int k=0;k<15;k++)
identifer1[kk].identitype[k]=id
kk++;
pop(3);
top_seq1(s1,top);
goto1(top,"D");
push_seq2(s3,"_");
}
}
else if(j>0)
action1(top,get1);
}
}
void action2(int i,string s)
{
int pos,j;
if(judge(v2,13,s))
j=address(v2,13,s);
pos=analysis_table2[i][j];
char str[15];
change(str,s);
out_seq1(s1);printf("\t\t");out_seq2(s2);printf("
if(pos==100)
{
cout<<"分析成功!"<
cout<<"*****************************************
}
else
printf("action[%d,%s]=S%d状态%d入栈\n",i,str,pos,
push_seq1(s1,pos);
push_seq2(s2,s);
push_seq2(s3,"_");
get1=in[addr];
addr++;
}
void goto2(int i,string s)
{
int pos,j;
if(judge(v2,13,s))
j=address(v2,13,s);
pos=analysis_table2[i][j];
char str[15];
change(str,s);
printf("goto[%d,%s]=%d\n",i,str,pos);
push_seq1(s1,pos);
push_seq2(s2,s);
}
void slr2()
{
t='1';
clear(s1,s2,s3);
push_seq1(s1,0);
push_seq2(s2,"#");
push_seq2(s3,"_");
get1=in[addr];
addr++;
string p[10];int num=0;
p[num]=ins[addr-1];num++;
int top,j;
char str1[15];
while(1)
{
j=address(v2,13,get1);
top_seq1(s1,top);
if(top==100)
{
addr--;
return;
}
j=analysis_table2[top][j];
if(j>0)
action2(top,get1);
else if(j<0)
{
if(j==-1)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(4);
top_seq1(s1,top);
goto2(top,"A");
for(int i=0;i
if((screamp(identifer1[i].identiname,p[0]))
{
change(str1,identifer1[i].identiname);
emit("=",E,"_",str1);
push_seq2(s3,str1);
}
}
else if(j==-2)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(3);
top_seq1(s1,top);
goto2(top,"E");
E1=E;
E=newtemp();
emit("+",E1,T,E);
push_seq2(s3,E);
}
else if(j==-3)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(1);
top_seq1(s1,top);
goto2(top,"E");
E=T;
push_seq2(s3,T);
}
else if(j==-4)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(3);
top_seq1(s1,top);
goto2(top,"T");
T1=T;
T=newtemp();
emit("*",T1,F,T);
push_seq2(s3,T);
}
else if(j==-5)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(1);
top_seq1(s1,top);
goto2(top,"T");
T=F;
push_seq2(s3,F);
}
else if(j==-6)
{
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(3);
top_seq1(s1,top);
goto2(top,"F");
F=E;
push_seq2(s3,E);
}
else if(j==-7)
{
p[num]=ins[addr-2];num++;
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(1);
top_seq1(s1,top);
goto2(top,"F");
for(int i=0;i
if((screamp(identifer1[i].identiname,p[num-
{
change(str1,identifer1[i].identiname);
F=str1;
push_seq2(s3,str1);
}
}
else if(j==-8)
{
p[num]=ins[addr-2];num++;
out_seq1(s1);printf("\t\t");out_seq2(s2);pri
pop(1);
top_seq1(s1,top);
goto2(top,"F");
for(int i=0;i
if((screamp1(constant1[i].constantname,p[nu
{
F=constant1[i].constantname;
push_seq2(s3,F);
}
}
}
}
}
void printslr1()
{
cout<<"\n****************************语法语义分析情况**
cout<<"状态栈\t\t符号栈\t\t语义栈\t\t动作说明"<
}
void Initscanner()
{
reserveedword1[1].word="int";
reserveedword1[2].word="char";
reserveedword1[3].word="float";
reserveedword1[4].word="void";
reserveedword1[5].word="const";
reserveedword1[6].word="for";
reserveedword1[7].word="if";
reserveedword1[8].word="else";
reserveedword1[9].word="then";
reserveedword1[10].word="while";
reserveedword1[11].word="switch";
reserveedword1[12].word="break";
reserveedword1[13].word="begin";
reserveedword1[14].word="end";
}
void Scanner()
{
cout<<"生成的二元式为:"<
while(ch!='#')
{
Lexscan();
}
cout<
}
void Lexscan()
{
infile.get(ch);
if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))
Isalpha(ch);
else if((ch>='0')&&(ch<='9'))
Isnumber(ch);
else
Isother(ch);
}
void Isalpha(char s)
{
char keep[15];
int i=0;
keep[i]=s;
i++;
while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<=
{
infile.get(ch);
keep[i]=ch;
i++;
}
keep[i-1]='\0';
for(int k=1;k<=14;k++)
{
if(screamp(keep,reserveedword1[k].word))
{
Output(1,i-1,keep);
in[addr]=keep;ins[addr]=keep;
addr++;
return;
}
}
if(m==0)
{
for(k=0;k
identifer1[m].identiname[k]=keep[k];
Output(2,0,keep);
in[addr]="id";ins[addr]=keep;
addr++;
m++;
}
else
{
for(int j=0;j
{
if(screamp(keep,identifer1[j].identiname))
{
Output(2,j,keep);
in[addr]="id";ins[addr]=keep;
addr++;
infile.seekg(-1,ios::cur);
return;
}
}
for(k=0;k
identifer1[m].identiname[k]=keep[k];
Output(2,m,keep);
in[addr]="id";ins[addr]=keep;
addr++;
m++;
}
if(ch=='#')
return;
else
infile.seekg(-1,ios::cur);
}
void Isnumber(char s)
{
char integer[15];
int i=0;
integer[i]=s;
i++;
while((ch>='0')&&(ch<='9'))
{
infile.get(ch);
integer[i]=ch;
i++;
}
integer[i-1]='\0';
if(n==0)
{
constant1[n].constantname=integer;
Output(3,0,integer);
in[addr]="num";ins[addr]=integer;
addr++;
n++;
}
else
{
for(int j=0;j
{
if(screamp(integer,constant1[n].constantname)
{
Output(3,j,integer);
in[addr]="num";ins[addr]=integer;
addr++;
return;
}
}
constant1[n].constantname=integer;
Output(3,n,integer);
in[addr]="num";ins[addr]=integer;
addr++;
n++;
}
if(ch=='#')
return;
else
infile.seekg(-1,ios::cur);
}
void Isother(char s)
{
char temp[15];
int i=0;
temp[i]=s;
i++;
switch(temp[0])
{
case '+':
{
cout<<"(+,-)\n";
in[addr]="+";
ins[addr]="+";
addr++;
break;
}
case '-':
{
cout<<"(-,-)\n";
in[addr]="-";
ins[addr]="-";
addr++;
break;
}
case '*':
{
cout<<"(*,-)\n";
in[addr]="*";
ins[addr]="*";
addr++;
break;
}
case '(':
{
cout<<"((,-)\n";
in[addr]="(";
ins[addr]="(";
addr++;
break;
}
case ')':
{
cout<<"(),-)\n";
in[addr]=")";
ins[addr]=")";
addr++;
break;
}
case '=':
{
cout<<"(=,-)\n";
in[addr]="=";
ins[addr]="=";
addr++;
break;
}
case ';':
{
cout<<"(;,-)\n";
in[addr]=";";
ins[addr]=";";
addr++;
in[addr]="#";
ins[addr]="#";
addr++;
break;
}
case ',':
{
cout<<"(,,-)\n";
in[addr]=",";
ins[addr]=",";
addr++;
break;
}
}
}
void Output(int i,int j,char ss[15])
{
switch(i)
{
case 1:
{
cout<<"(";
for(int k=0;k
{cout<
cout<<","<<"-"<<")\n";
break;
}
case 2:
{
cout<<"(id,"<
break;
}
case 3:
{
cout<<"(num,"<
break;
}
}
}
void main()
{
infile.open("input.txt",ios::in);
if(!infile)
{
cerr<<"读取的文件打开失败!"<
exit(1);
}
Initscanner();
Scanner();
infile.close();
printslr1();
addr=0;
while(!screamp1(in[addr],""))
{
int j=0;
for(int i=1;i<=14;i++)
if(screamp1(in[addr], reserveedword1[i].word)
j=100;
if(j==100)
slr1();
else
slr2();
}
char_Table();
print(s);
}
课程设计任务书 课题名称 指导教师 《编译原理》课程设计 完成时间 职称 学生姓名 班级 总体设计要求 总体设计要求: 课程设计内容共给定 1 个题目,每个学生按照课程设计要求,在规定的两周时间内独立完成。 题目: 编译程序构造 涉及内容: 词法分析、语法分析、语义分析生成中间代码 工作内容及时间进度安排 第一周、周1:设计动员,布置课程设计任务,查阅资料,制定方案,进行程序方案设计。 第一周、周 2-周 5:编写和调试程序 第二周、周 1-周 3:编写和调试程序 第二周、周 4:整理,撰写设计报告。 第二周、周 5:验收,提交设计报告,评定成绩。 毕业设计成果 1、课程设计报告书一份 2、源程序清单一份 3、成果使用说明书一份
内容摘要 `````````````````` 第 1 章 绪论 1.1、课程设计目的 1.2、课程设计意义 1.3、课程设计要求 1.4、课程设计内容 1.4.1、题目 编译程序构造 1.4.2、内容 涉及词法分析、自下而上语法分析程序的实现:SLR(1)分析器的实现以及 生成中间代码。 1.4.3、具体要求 根据 LR 分析算法构造 SLR(1)分析程序,并完成语法分析动作(当需要一 个单词时,调用词法分析程序获取),同时完成语义分析生成四元式输出。要求 程序具有通用性,改变文法时只需改变程序的数据初值,无需改变程序主体; 要求完成一条说明语句、一条算数表达式和赋值语句的翻译,生成中间代码。 变量说明语句的文法及相应的语义子程序:.att 表示数据类型属性,fill 函数 表示将单词 id 及其类别属性填写符号表。 - 2 -
{acc} (0)S→D; { fill(id,int);D.att=int; } (1)D→int id {fill(id,float); D.att=float; } (2)D→float id (3)D→D(1),id { fill(id,D(1).att);D.att=D(1).att; } 算数表达式和赋值语句的文法及相应的语义子程序。 (1)A→id=E; (2)E→E(1)+T {p=lookup(id.name); emit(E.PALCE, , p);} {E.PALCE=newtemp(); (3)E→T (4)T→T(1)*F (5)T→F (6)F→(E) (7)F→id (8)F→num emit(+,E(1).PALCE,T.PALCE,E.PALCE)} {E.PALCE=T.PALCE;} {T.PALCE=newtemp(); emit(+,T(1).PALCE,F.PALCE,T.PALCE)} {T.PALCE=F.PALCE;} { F.PALCE=E.PALCE;} {P=LOOKUP(id.name); F.PALCE=P;} { P=LOOKUP(num.value) F.PALCE=P;} 构造其用于 SLR(1)分析的识别活前缀的 DFA 以及 action 表和 goto 表。然后 编程实现。(关于词法分析部分只需识别出与此文法相关的单词即可(+,*,(,), id,=))。 1.4.4、程序设计提示 (1)分析栈设计时可以用一个栈完成,也可以设计三个栈:一个符号栈, 一个状态栈,一个语义栈,则归约时,则需要在符号栈中退掉 n 个符号,在状态 栈中退掉 n 个符号(n 为产生式符号个数),语义栈中退掉 n 个符号对应的语义; (2)终结符表和非终结符表的组织和预测分析程序中相同(将符号对应到 一个数字,表示在分析表中对应的下标)。 (3)action 表中的错误处理:简化的错误处理:当查找 action 表出现空白 时,则当前单词无法移进和规约,可简单的认为当前单词为多余的单词,则抛弃 当前单词,读下一单词继续分析。 1.4.5、测试数据 源文件中数据: int area,r; r=1; area=r*r+r; 程序要求输出二元式序列、符号表、语法分析过程、四元式序列。 - 3 -
1.4.6、程序扩展要求 第 2 章 程序总体设计 - 4 -
第 3 章 程序详细设计与实现 3.1、词法分析 首先定义结构体 typedef struct { int data[max]; int top; }seqstack1; typedef struct { //状态栈 //符号栈 string data[max]; int top; }seqstack2; struct reserveedword//保留字表结构 { string word; char value; }reserveedword1[maxsize]; struct identifer//标识符表结构 { char identiname[15]; char identitype[15]; int address; }identifer1[maxsize]; struct constant//常量表结构 { string constantname; string value; - 5 -
int constantaddress; }constant1[maxsize]; 词法分析主要函数结构: void Initscanner() void Isalpha(char s) void Isnumber(char s) void Isother(char s) void Lexscan() //该函数用于用 C 语言当中常见的关键字初始化保留表 //用于判断读入的字符是不是字母 //用于判断读入的字符是不是数字 //判断除数字与字母之外的其他字符 //用于循环从程序中读入字符并判断应调用那个判断函 数字符 void Output(int i,int j,char ss[15]) //输出二元式 本模块程序的伪代码如下: 打开文件 infile.open("input.txt",ios::in); if(!infile) { cerr<<"读取的文件打开失败!"<='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))) Isalpha(ch){ Output}; else if((ch>='0')&&(ch<='9')) Isnumber(ch) { Output}; Isother(ch) { Output}; 词法分析器中从源文件读出一个单词,判断其类型是关键字、标识符还是普 通符号,根据其类型为结构体各项赋值,并将其传给语法分析函数。 - 6 -
3.2、语法分析 由于说明语句与算术表达式和赋值语句所使用的是不同的文法,所以两者的 ACTION 表和 GOTO 表也不一样,本次课设采用二维数组存放 ACTION 表和 GOTO 表信息,其中移进用大于 0 的数表示,归约用小于 0 的数表示,成功用 100 表示 (acc),其他处用 0 表示,查表时遇到相应的数进行相应的操作。 其中,归约部分需要根据其产生式的信息进行,所以程序中有如下定义: string v1[8]={"int","float",";",",","id","#","D","S"}; //存放说明文法当中的字符 string v2[13]={"#","id","=","num",";","+","*","(",")","F","A","E","T"};//存放算本 文法当中的字符 根据状态转换图(DFA)构造 SLR(1)分析表: 其中说明文法和算术文法分别构造,同时在每个表当中既有 action 表 又有 goto 表 int analysis_table1[10][8]={3,4,0,0,0,0,2,1, int analysis_table2[17][13]={0,2,0,0,0,0,0,0,0,0,1,0,0, 0,0,0,0,0,100,0,0, 0,0,5,6,0,0,0,0, 0,0,0,0,7,0,0,0, 0,0,0,0,8,0,0,0, 0,0,0,0,0,-1,0,0, 0,0,0,0,9,0,0,0, 0,0,-2,-2,0,0,0,0, 0,0,-3,-3,0,0,0,0, 0,0,-4,-4,0,0,0,0}; 100,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,0,0,0,0,0,0,0,0,0,0, 0,9,0,8,0,0,0,7,0,6,0,4,5, 0,0,0,0,10,11,0,0,0,0,0,0,0, 0,0,0,0,-3,-3,12,0,-3,0,0,0,0, 0,0,0,0,-5,-5,-5,0,-5,0,0,0,0, 0,9,0,8,0,0,0,7,0,6,0,13,5, 0,0,0,0,-8,-8,-8,0,-8,0,0,0,0, 0,0,0,0,-7,-7,-7,0,-7,0,0,0,0, -1,0,0,0,0,0,0,0,0,0,0,0,0, 0,9,0,8,0,0,0,7,0,6,0,0,14, 0,9,0,8,0,0,0,7,0,15,0,0,0, 0,0,0,0,0,11,0,0,16,0,0,0,0, 0,0,0,0,-2,-2,12,0,-2,0,0,0,0, 0,0,0,0,-4,-4,-4,0,-4,0,0,0,0, 0,0,0,0,-6,-6,-6,0,-6,0,0,0,0}; 语法分析当中各个函数说明及伪代码: void action1(int i,string s) //通过词法分析传过来的值判断移进动作 三个栈(状态栈,符号栈,语义栈)应该读入哪些值。 void action2(int i,string s) //同 action1 只是表示算术文法 - 7 -
int address(string m[],int i,string x) void goto1(int i,string s) //获得在分析表中的列下标 //通过判断栈中的元素,来判断用那个产生 式来进行规约 void goto2(int i,string s) void slr1() void slr1() 伪代码如下: //对说明文法进行语法分析 //对算术文法进行语法分析 //同 goto1 先判断是说明文法还是算术文法 If(说明文法) Slr1() { push_seq1(s1,0); push_seq2(s2,"#"); push_seq2(s3,"_"); while(1) { j=address(v1,8,get1); top_seq1(s1,top); j=analysis_table1[top][j]; if(j<0) { { if(j==-1) 用 S->D;归约 else if(j==-2) 用 D->int id 归约 else if(j==-3) else if(j==-4) 用 D->float id 归约" 用 D->D,id 归约" } else if(j>0) action1(top,get1); } else } Slr2() { push_seq1(s1,0); push_seq2(s2,"#"); push_seq2(s3,"_"); while(1) { j=address(v2,13,get1); - 8 -
分享到:
收藏