WHILE循环语句的翻译程序设计(LL(1)法、输出三地址表示)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include"iostream"
using namespace std;
#define MaxiProgramNumber 888 //源程序最大字符的个数
#define MaxiWordLength 18 //标示符和关键字最长字符的个数
#define MaxiTokenNumer 118 //标识符能包含的最多的字符个数
/*………………………………………………………………………………………………*/
#define MaxiWordLength1 18
#define MaxiTokenNumer1 118
/*………………………………………………………………………………………………*/
char Ecode[MaxiTokenNumer1][MaxiWordLength1];
int Top=0;
int nID=1; //初始化
/*……………………………下面定义栈结构,栈中的元素是一个结构体………………*/
typedef struct
{
int add;
int next;
char str[MaxiWordLength1];
}ADDL; //ADDL用于识别WHILE,DO
ADDL L[MaxiTokenNumer1]; //L为定义的结构体名
int nL=0;
int nadd=1; //初始化
/*………………………………输入串栈,栈中元素为结构体……………………………*/
typedef struct
{
int ID;
char b[MaxiWordLength];
}link;
link Token[MaxiTokenNumer];
link Token2[MaxiTokenNumer];
int nTokenNumer=1; //标志位置
char a[MaxiProgramNumber]; //数组用于装入源程序
int nLength=0; //用于指向数组中的元素
/*……………………………函数声明(词法分析部分用到的函数)………………………*/
void GetProgram(); //把源程序装入数组a
char GetChr(); //将数组a中的元素读出
int Judge(char& chr); //用于判断'\0'
int IsLetter(char c); //用于判断是否为字母
void Input(char* p,char c,int& nx); //标识符或关键字进入指针p指向的数组第nx+1个元素
void Save(char* word,int x); //将关键字或标志符或算符装入Token
void Getcode();
/*……………………………函数声明(语法分析部分用到的函数)………………………*/
void Pop(); //出栈
void InputS();
void InputE1();
void InputE2();
void InputE3();
void InputA();
int firstset();
int panduanSEA(); //识别非终结符
int EStrcmp();
/*…………………………………………词法分析部分……………………………………*/
int Wordanalyze()
{
int jieshu=0;
char chr;
cout<<"请输入一段while语句(以#为结束标志):"<<endl<<endl
;GetProgram();
//把源程序装入数组a
int x;
char word[MaxiWordLength]; //声明临时数组
while((chr=GetChr())!='\0')
{
if(!(Judge(chr)))
{
break;
} //跳过空格和回车取元素
x=0;
word[x]='\0'; //清空
if(IsLetter(chr))
{ jieshu=1;
while(IsLetter(chr))
{
Input(word,chr,x); //是字符就将其装入数组word
chr=GetChr();
}
if(chr=='>' || chr=='='||chr=='<')
nLength=nLength-1; //指向算符
word[x]='\0';
Save(word,x); //将关键字或标志符或算符装入Token
}
else if(chr=='>') //将'>'装入Token
{
Input(word,chr,x);
word[x]='\0';
Save(word,x);
}
else if(chr=='=') //将'='装入Token
{
Input(word,chr,x);
word[x]='\0';
Save(word,x);
}
else if(chr=='<') //将'<'装入Token
{
Input(word,chr,x);
word[x]='\0';
Save(word,x);
}
else
{
printf("输入出错!\n"); //出错处理
jieshu=0;
return 0;
}
} //这个函数的作用是将输入符号放入Token
if(jieshu==1) //词法分析结束
{
Getcode();
cout<<"******************词法分析阶段******************"<<endl;
printf("词法分析结果:\n<种类,单词>\n");
for(int i=1;i<nTokenNumer;i++) //输出词法分析结果
{
printf("<");
printf("%d",Token[i].ID);
printf(",");
printf("%s",Token[i].b);
printf(">\n");
strcpy(Token2[i].b,Token[i].b);//将输入的符号拷贝在Token2中
}
for(int d=1;d<nTokenNumer;d++) //将标识符号替换成id
{
if(Token[d].ID==6)
{
strcpy(Token[d].b,"id");
}
}
strcpy(Token[nTokenNumer].b,"#");
Token[nTokenNumer].ID=7; //'#'的种别编码为7
return 1;
}
// getch();
int abcd;
cin>>abcd;
}
void GetProgram() //把源程序装入数组a
{
char ch;
while((ch=getchar())!='#')
{
if(nLength>=MaxiProgramNumber-2)
break;
else
a[nLength++]=ch;
}
a[nLength]='\0';
nLength=0;
}
char GetChr() //将数组a中的元素读出
{
if(nLength>=MaxiProgramNumber-1)
return '\0';
else
return a[nLength++];
}
int Judge(char& chr) //用于判断'\0',返回值为0时为'\0'
{
while(chr==10 || chr==32) //当chr为空格和换行时
{
chr=GetChr();
if(chr=='\0')
{
return 0;
}
}
return 1;
}
int IsLetter(char c) //用于判断是否为字母或数字
{
if(c>='a' && c<='z' || c>='A' && c<='Z'||c>='0'&&c<='9')
return 1;
else
return 0;
}
void Input(char* p,char c,int& nx) //标识符或关键字进入指针p指向的数组第nx+1个元素
{
if(nx<MaxiWordLength-1)
{
p[nx]=c;
nx++;
}
}
void Save(char* p,int x) //将关键字或标志符或算符装入Token
{
for(int i=0;i<=x;i++)
Token[nTokenNumer].b[i]=p[i];
nTokenNumer=nTokenNumer+1;
}
/*…………………………为不同的输入符号赋予不同的种别编码……………………*/
void Getcode()
{
for(int i=1;i<nTokenNumer;i++)
{
if(strcmp(Token[i].b,"while\0")==0)
Token[i].ID=1;
else if(strcmp(Token[i].b,"do\0")==0)
Token[i].ID=2;
else if(strcmp(Token[i].b,">\0")==0)
Token[i].ID=3;
else if(strcmp(Token[i].b,"=\0")==0)
Token[i].ID=4;
else if(strcmp(Token[i].b,"<\0")==0)
Token[i].ID=5;
else
Token[i].ID=6;
}
}
/*………………………………………语法分析过程……………………………………*/
int ExpressionAnalyse() //语法分析
{
cout<<"******************语法分析阶段******************"<<endl;
printf("\n语法分析结果:\n");
strcpy(Ecode[Top++],"#"); //将#压栈
strcpy(Ecode[Top++],"S"); //将S压栈
int FLAG=1; //语法分析未结束标志
while(FLAG)
{
int f1=0;
f1=panduanSEA();
if(f1==1)
{
cout<<" S->while E do A"<<endl;
InputS();
}
else if(f1==2)
{ int f3=0;
f3=firstset();
if(f3==1)
{
cout<<" E->id>id"<<endl;
InputE1();
}
else if(f3==2)
{
cout<<" E->id=id\n"<<endl;
InputE2();
}
else
{
cout<<" E->id<id"<<endl;
InputE3();
}
}
else if(f1==3)
{
cout<<" A->id=id"<<endl;
In
putA();
}
else
{
int f2=0;
f2=EStrcmp();
if(f2==1) //识别出关键字
{
Pop();
nID=nID+1;
}
else if(f2==3) //识别出#,分析结束
{
cout<<endl&
lt;<"语法正确!"<<endl;
FLAG=0;
return 1;
}
else
{
cout<<endl<<"语法出错啦!"<<endl;
FLAG=0;
return 0;
}
}
}
}
void InputS() //压栈
{
Pop();
strcpy(Ecode[Top++],"A");
strcpy(Ecode[Top++],"do");
strcpy(Ecode[Top++],"E");
strcpy(Ecode[Top++],"while");
}
void InputE1() //压栈
{
Pop();
strcpy(Ecode[Top++],"id");
strcpy(Ecode[Top++],">");
strcpy(Ecode[Top++],"id");
}
void InputE2() //压栈
{
Pop();
strcpy(Ecode[Top++],"id");
strcpy(Ecode[Top++],"=");
strcpy(Ecode[Top++],"id");
}
void InputE3() //压栈
{
Pop();
strcpy(Ecode[Top++],"id");
strcpy(Ecode[Top++],"<");
strcpy(Ecode[Top++],"id");
}
void InputA() //压栈
{
Pop();
strcpy(Ecode[Top++],"id");
strcpy(Ecode[Top++],"=");
strcpy(Ecode[Top++],"id");
}
void Pop() //出栈操作
{
Top=Top-1;
}
int firstset()
{
if(strcmp(Token2[3].b,">")==0)
return 1;
if(strcmp(Token2[3].b,"=")==0)
return 2;
if(strcmp(Token2[3].b,"<")==0)
return 3;
}
int panduanSEA() //识别非终结符
{
if(strcmp(Ecode[Top-1],"S")==0)
return 1;
else if(strcmp(Ecode[Top-1],"E")==0)
return 2;
else if(strcmp(Ecode[Top-1],"A")==0)
return 3;
else
return 4;
}
int EStrcmp() //识别while和do关键字
{
if(strcmp(Ecode[Top-1],"#")==0)
{
if(strcmp(Token[nID].b,"#")==0)
return 3;
}
else if(strcmp(Ecode[Top-1],Token[nID].b)==0)
{
if(strcmp(Ecode[Top-1],"while")==0)
{
L[nL].add=nadd++;
L[nL].next=nadd++;
strcpy(L[nL].str ,"while");
nL++;
}
if(s
trcmp(Ecode[Top-1],"do")==0)
{
L[nL].add=nadd++;
L[nL].next=L[nL-1].add;
strcpy(L[nL].str ,"do");
nL++;
}
return 1;
}
else
return 0;
cout<<Token[2].b<<endl;
}
/*……………………………………语义分析……………………………………*/
void main()
{
cout<<"程序所用的文法:"<<endl;
cout<<"S->while E do A"<<endl;
cout<<"E->id1>id2|id1=id2|id1<id2"<<endl;
cout<<"A
->id3=id4"<<endl;
cout<<"(id1,id2,id3,id4代表标识符)"<<endl;
if(Wordanalyze()) //词法分析成功
{if(ExpressionAnalyse()) //语法分析也成功
{int i;
L[nL].add=nadd;
for(i=0;i<nL;i++)
{if(strcmp(L[i].str,"while")==0) //输出3地址
{ cout<<endl;
cout<<"正确的语义输出为:"<<endl;
cout<<"L0: if "<<Token2[2].b<<" > "<<Token2[4].b<<" goto L2"<<endl;
cout<<"L1: if not goto L4"<<endl; }
else
{cout<<"L2: "<<Token2[6].b<<":="<<Token2[8].b<<endl;
cout<<"L3: "<<"goto L0"<<endl;
cout<<"L4: "<<endl;
}
}
}
}
}