📄 22.txt
字号:
#include"stdafx.h"
#include"stdio.h"
#include<string.h>
#include"conio.h" //要使用函数getch
#include"stdlib.h" //要使用函数itoa
#include<iostream>
using namespace std;
char shuru[80],token[8]; //shuru数组是保存字符串;
char ch;
int syn,p,m,n,sum,kk,q,tx=0; //sum保存字符数字的值;syn是字符类型标识
char *Guanjz[2]={"while","do"}; //关键字集合
struct{
char result[8];
char ag1[8];
char op[8];
char ag2[8];
}Sandz[20];//保存4元式
void scaner(); //词法分析程序声明;每次调用此函数,会得到一个单词
int lrparser();//语法分析声明
int G();
char *E();
char *expression();//表达式的分析,加减法运算的分析
char *factor();//负责取token并进行下一个的词法分析
char *newtemp();
void emit(char *result,char *ag1,char *op,char *ag2);//给结构体变量Sandz[]赋值
int main() //主函数
{int j;
p=0;
cout<<"输入字符串:"<<endl;
do
{ch=getchar(); //获取输入字符串,以#作结束符,并且#是数组shuru[]的最后一个字符
shuru[p++]=ch;
}while(ch!='#');
p=0;
kk=0;
q=0;
scaner(); //对输入的字符串进行词法分析;获取一个单词
lrparser(); //对输入的单词进行语法分析
if(q>19) //结构体数组Sandz[]大小为20
cout<<"语法分析太长!"<<endl;
else
for(j=0;j<q-1;j++)
cout<<j<<": "<<Sandz[j].result<<"="<<Sandz[j].ag1<<Sandz[j].op<<Sandz[j].ag2<<endl;//将语义分析过程打印成四元式格式
cout<<j<<": "<<Sandz[j].op<<" "<<Sandz[j].ag1<<" "<<Sandz[j].ag2<<" "<<Sandz[j].result<<endl;
cin>>ch;
return 0;
}
void scaner()
{m=0;
sum=0;
for(n=0;n<8;n++)
token[n]=NULL; //将token清空
ch=shuru[p++]; //获取缓冲区一个字符
while(ch==' ')
ch=shuru[p++]; //是空格时,忽略,获取下一个
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') //是字母时
{while(ch>='a'&&ch<='z' || ch>='A'&&ch<='Z' || ch>='0'&&ch<='9')
{ token[m++]=ch; //字符保存到TOKEN
ch=shuru[p++]; //获取下一个字符
}
token[m++]='\0';//TOKEN得到了单词
p--;//指针回到不满足条件的那个字符
syn=10;//TOKEN中保存的字符类型是10,即变量或关键字
for(n=0;n<2;n++)
if(strcmp(token,Guanjz[n])==0) //与关键字集合比较,若相同,则该TOKEN保存的类型为对应的关键字
{syn=n+1;break;}
}
else
if(ch>='0'&&ch<='9') //是数字时,保存到num中,字符类型是11,即数字
{while(ch>='0'&&ch<='9')
{token[m++]=ch;
ch=shuru[p++];
}
token[m++]='\0';
p--;
syn=11;
}
else
switch(ch) //是符号时
{case'<':token[m++]=ch; //是<或<=时
ch=shuru[p++];
if(ch=='=')
{ syn=22;
token[m++]=ch;
token[m++]='\0';
}
else
{ syn=20;
token[m++]='\0';
p--;
}
break;
case'>':token[m++]=ch; //是>或>=时
ch=shuru[p++];
if(ch=='=')
{ syn=24;
token[m++]=ch;
token[m++]='\0';
}
else
{syn=23;
token[m++]='\0';
p--;
}
break;
case'=':token[m++]=ch; //是==或=时
ch=shuru[p++];
if(ch=='=')
{ syn=17;
token[m++]=ch;
token[m++]='\0';
}
else
{ syn=18;
token[m++]='\0';
p--;
}
break;
case'!':token[m++]=ch; //是!=或!时
ch=shuru[p++];
if(ch=='=')
{ syn=19;
token[m++];
token[m++]='\0';
}
else
{ syn=9;
token[m++]='\0';
p--;
}
break;
case'+':syn=13;token[m++]=ch;token[m++]='\0';break;
case'-':syn=14;token[m++]=ch;token[m++]='\0';break;
case'(':syn=27;token[m++]=ch;token[m++]='\0';break;
case')':syn=28;token[m++]=ch;token[m++]='\0';break;
case'{':syn=29;token[m++]=ch;token[m++]='\0';break;
case'}':syn=30;token[m++]=ch;token[m++]='\0';break;
case'#':syn=0; token[m++]=ch;token[m++]='\0';break;
default:syn=-1;
}
}
int lrparser() //语法分析
{ kk=0;//这里是用来判断是否出错
if(syn==-1)
{ cout<<"输入了不能识别的符号,ERROR!"<<endl;}
if(syn==2) //该单词为do
{ scaner();
if(syn!=29)//该单词不是{
{cout<<"do后面没有{,ERROR!"<<endl;kk=1;}
else
{scaner();
G();//分析{后面的符号,如果不是变量、数字、运算符时,退出
}
if(syn!=30)
{cout<<"do后面没有}结束,ERROR!"<<endl;kk=1;}
else
{scaner();
if(syn==1)//该单词为while
{ scaner();
if(syn!=27)//该单词不是(
{cout<<"while后面没有(,ERROR!"<<endl;kk=1;}
else
{ scaner();
E();//分析(后面的符号,如果不是变量、数字、比较符时,退出
}
if(syn!=28) //该单词不是)
{cout<<"while后面没有),ERROR!"<<endl;kk=1;}
if(kk!=1)
{cout<<"分析成功!"<<endl;}
}
else
{cout<<"do后面没有while,ERROR!"<<endl;}
}
}
else
{cout<<"没有找到do,ERROR!"<<endl;}
return 0;
}
int G() //赋值运算
{ char tt[8],eplace[8];
if(syn==10) //输入类型是变量
{ strcpy(tt,token); //将变量名复制到tt中
scaner();
if(syn==18) //如果输入类型是赋值号=
{ scaner();
strcpy(eplace,expression());//将赋值号后面的值放入eplace中,该值用t1,t2。。。表示
emit(tt,eplace,"","");//此步骤写成4元式
}
else
{ cout<<"没有赋值"<<endl;kk=1;}
}
else
{ cout<<"输入的变量错误"<<endl;kk=1;}
return 0;
}
char *expression() //表达式的值,算加减法
{char *result,*ag1,*ag2,*op;//tt保存符号
result=new char;
ag1=new char;
ag2=new char;
op=new char;
if(syn==10||syn==11)//如果得到的是变量或数字,将因数放入ag1中
strcpy(ag1,factor());
while(syn==13 || syn==14) //是+或-号时
{ if (syn==13)
strcpy(op,"+");
else
strcpy(op,"-");
scaner();
strcpy(ag2,factor());//假设第二个操作数是变量或数字
strcpy(result,newtemp());//将结果记录为t1、t2、t3、....
emit(result,ag1,op,ag2);//保存为4元式
}
return(result);
}
char *factor() //取单词并进行下一个的词法分析
{ char *value;
value=new char;
strcpy(value,token);//将单词保存到value中,再扫描下个单词
scaner();
return(value);//将得到的单词返回
}
char *newtemp()//表达式的值
{ tx++;
char lx;
lx=tx+'0';
char m[8];
m[0]='t';
m[1]=lx;
m[2]='\0';
return(m);
}
void emit(char *result,char *ag1,char *op,char *ag2)
{strcpy(Sandz[q].result,result);
strcpy(Sandz[q].ag1,ag1);
strcpy(Sandz[q].op,op);
strcpy(Sandz[q].ag2,ag2);
q++;
}
char *E()
{char wei[20];
if(syn==10)
{ strcpy(wei,factor());
if(syn<=24 && syn>=17)
{strcat(wei,token);//将比较符放到数组wei中;
scaner(); //扫描下一个单词;
if(syn==10||syn==11)
{strcat(wei,token);//将变量或数字放到数组wei中;
emit("1",wei,"if","goto");//": if "<<wei<<" goto 1"<<endl;
scaner();
}
else
{cout<<"条件判断表达式有错误,ERROR!"<<endl;kk=1;}
}
else
{cout<<"条件判断表达式有错误,ERROR!"<<endl;kk=1;}
}
else
{cout<<"条件判断表达式有错误,ERROR!"<<endl;kk=1;}
return wei;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -