📄 语法分析程序.cpp
字号:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef struct stack{
char name[20];
int cod;
int addr;
}stack;
typedef struct equ{
int op;
int op1;
int op2;
int result;
}equ;
typedef struct var{
char name[20];
int addr;
int type;
int value;
}var;
# define EXP_LEN 100
# define EQU_LEN 1024
# define ONE 50001
# define ZERO 50000
# define E_EXPR 7
# define IF 8
# define WHILE 9
# define FOR 10
# define REPEAT 11
# define B_EXP 12
FILE *TokenFin;
FILE *SymbleFin;
FILE *EquFout;
int code;
int address;
int LineOfPro;
int LineOfEqu;
stack var_list[EXP_LEN];
stack expr[EXP_LEN];
equ Equ[EQU_LEN];
var TempList[EXP_LEN];
char ID[20];
int var_count;
int len_count;
int pos;
int now_addr;
int temp_count;
int error_count;
int let_count;
int E_Contrl;
int E_rtn;
int True_address;
int False_address;
int gen_pos;
int EquPush(int op,int a,int b,int r);
void GetNext();
void Error(int num);
int Num(char cc);
int gen(int op,int a,int b,int r);
void Declear();
void InitStack();
void Push(int cod,int addr);
int NewTemp();
void BackPatch(int addr,int addr2);
/*******布尔表达式分析函数****************/
int B_Analize();
void B_Init();
int B_OR();
int B1_OR(int a);
int L_AND();
int L1_AND(int a);
int M_NOT();
int K_END();
int K_CMP();
/*******算术表达式分析函数************/
int E_Analize();
void E_Init();
int E_AddSub();
int E1_AddSub(int a);
int T_MulDiv();
int T1_MulDiv(int a);
int F_Number();
/*******语句分析函数*************/
void parser();
int S_Let(int a);
int S_If();
int S_While();
int S_For();
int S_Repeat();
int S_Begin();
int L_Analize();
int main(){
parser();
return 0;
}
void parser(){
int gen_pos=0;
int Line;
int i;
char ch1;
pos=0;
let_count=0;
error_count=0;
LineOfPro=0;
address=0;
LineOfEqu=0;
temp_count=0;
now_addr=0;
len_count=0;
InitStack();
for(i=0;i<EXP_LEN-2;i++){
TempList[i].addr=0;
TempList[i].addr-=i;
TempList[i].name[0]='b';
TempList[i].name[1]='x';
}
/*建立四元式文件*/
EquFout=fopen("equ.txt","wt+");
if((TokenFin=fopen("token.txt","rt"))==NULL){
printf("Cannot open file token.txt strike any key exit!");
exit(1);
}
printf("* ******************** *\n");
printf("--------- 语法分析程序 -----------\n");
printf("* ******************** *\n");
printf("---------语法分析开始,请等待......------\n");
GetNext();
if(code==18){GetNext();
if(code==27){GetNext();
if(code==42){GetNext();LineOfPro++;}
if(code==25)Declear();
if(code==2){S_Begin();if(code!=38)Error(49);}
else Error(50);
}
else Error(2);
}
else Error(1);
Line=LineOfEqu;
LineOfEqu=0;
while(gen_pos<Line){
gen(Equ[gen_pos].op,Equ[gen_pos].op1,Equ[gen_pos].op2,Equ[gen_pos].result);
gen_pos++;
}
gen(0,0,0,0);
if(error_count) printf("共计 %6d 个错误!!小心啊!!\n",error_count);
else printf(" 不存在错误,分析成功,你好棒啊!!\n");
fclose(TokenFin);
printf(" \n\n结果如下: \n");
rewind(EquFout);
ch1=fgetc(EquFout);
while(ch1!=EOF){
printf("%c",ch1);
ch1=fgetc(EquFout);
}
fclose(EquFout);
}
void GetNext(){
int d1,d2,d3;
fscanf(TokenFin,"%d %s %d %d\n",&d1,ID,&d2,&d3);
code=d2;
address=d3;
}
void Error(int k){
switch(k){
case 1:printf(" 格式出错, 第1行少 'program' \n");break;
case 2:printf(" 格式出错, 第1行少程序名 \n");break;
case 3:printf(" 第%4d行, 说明语句出错 \n",LineOfPro);break;
case 4:printf(" 第%4d行, 赋值语句出错, 不匹配或其他错 \n",LineOfPro);break;
case 5:printf(" 第%4d行, 'end' 不匹配 \n",LineOfPro);break;
case 6:printf(" 第%4d行, 语句出错 \n",LineOfPro);break;
case 7:printf(" 第%4d行, 表达式语句出错 \n",LineOfPro);break;
case 8:printf(" 第%4d行, if 语句出错 \n",LineOfPro);break;
case 9:printf(" 第%4d行, while 语句出错 \n",LineOfPro);break;
case 10:printf(" 第%4d行, for 语句出错 \n",LineOfPro);break;
case 11:printf(" 第%4d行, repeat 语句出错 \n",LineOfPro);break;
case 12:printf(" 第%4d行, 布尔表达式语句出错 \n",LineOfPro);break;
case 49:printf(" 程序结束缺乏 . 号错误。 \n");break;
case 50:printf(" 未写任何语句!!\n\n");break;
case 51:printf(" 第%4d行, 缺乏' : '号错误\n",LineOfPro);break;
default:printf(" 未知错误!!\n\n");break;
}
error_count++;
return;
}
int gen(int op,int a,int b,int r){
LineOfEqu++;
switch(op){
case 0:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('0',EquFout);
fputc(' ',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 1:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc(':',EquFout);
fputc('=',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 2:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('+',EquFout);
fputc(' ',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 3:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('-',EquFout);
fputc(' ',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 4:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('*',EquFout);
fputc(' ',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 5:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('/',EquFout);
fputc(' ',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 6:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('j',EquFout);
fputc(' ',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 7:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('j',EquFout);
fputc('<',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 8:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('j',EquFout);
fputc('=',EquFout);fputc(' ',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 9:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('j',EquFout);
fputc('>',EquFout);fputc('=',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 10:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('j',EquFout);
fputc('<',EquFout);fputc('=',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
case 11:fprintf(EquFout,"%5d",LineOfEqu);
fputc(' ',EquFout);fputc('(',EquFout);
fputc(' ',EquFout);fputc('j',EquFout);
fputc('<',EquFout);fputc('>',EquFout);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",a);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",b);
fputc(' ',EquFout);
fprintf(EquFout,"%5d",r);
fputc(' ',EquFout);fputc(')',EquFout);fputc('\n',EquFout);break;
default:break;
}
return LineOfEqu;
}
/* ***说明变量语句分析******/
void Declear(){
int a=1,i=0,j=0;
int df;
InitStack();
i=0;
if(code==25){
GetNext();
if(code==2){Error(3);return;}
while(code!=2){
Push(code,address);
GetNext();
}
i=0;
var_count=0;
while(pos>0){
if(expr[i].cod==27){
i++;var_count++;pos--;
}
else{
if(expr[i].cod==40){
i++;pos--;
df=expr[i].cod;
if((df!=3)&&(df!=6)&&(df!=14)&&(df!=19)){
Error(3);return;
}
else{
i++;pos--;
if(expr[i].cod==42){i++;pos--;LineOfPro++;}
else {Error(51);LineOfPro++;}
}
}
else{if(expr[i].cod==37){i++;pos--;}
else{Error(3);return;}
}
}
}
for(i=0;i<EXP_LEN;i++){
var_list[i].addr=0;
var_list[i].cod=0;
for(j=0;j<30;j++) var_list[i].name[j]='\0';
}
if((SymbleFin=fopen("symble.txt","rt"))==NULL){
printf("Cannot open file symble.txt strike any key exit!");
exit(1);
}
i=0;
while(1){
fscanf(SymbleFin,"%d%d%s\n",&var_list[i].addr,&var_list[i].cod,var_list[i].name);
if(var_list[i].addr==0)break;
i++;
}
fclose(SymbleFin);
if((SymbleFin=fopen("symble.txt","wt"))==NULL){
printf("Cannot open file symble.txt strike any key exit!");
exit(1);
}
a=0;
fprintf(SymbleFin,"%3d 0 0\n",var_count);
while(a<i){
fprintf(SymbleFin,"%3d %3d %s\n",var_list[a].addr,var_list[a].cod,var_list[a].name);
a++;
}
fclose(SymbleFin);
}
return;
}
/***********赋值句分析************/
int S_Let(int a){
int addr,flag,rtn;
flag=0;
rtn=0;
InitStack();
if(code==27){
addr=address;
if(a) let_count=addr;
var_count++;
GetNext();
if(code==41){
flag=E_Analize();
if(flag!=0)rtn=EquPush(1,flag,0,addr);
}
}
else Error(4);
return rtn;
}
/**************算术表达式分析***********/
int E_Analize(){
int ans;
ans=0;
now_addr=0;
E_Init();
ans=E_AddSub();
if(expr[now_addr].addr!=0) Error(7);
return ans;
}
void E_Init(){
int flag=1,i;
pos=0;
E_rtn=0;
E_Contrl=1;
for(i=0;i<EXP_LEN;i++){
expr[i].addr=0;
expr[i].cod=0;
}
while(flag){
GetNext();
switch(code){
case 27:Push(code,address);break;
case 28:Push(code,address);break;
case 29:Push(code,address);break;
case 32:Push(code,address);break;
case 33:Push(code,address);break;
case 34:Push(code,address);break;
case 35:Push(code,address);break;
case 36:Push(code,address);break;
case 39:Push(code,address);break;
default: flag=0;break;
}
}
return;
}
int NewTemp(){
int a;
temp_count--;
a=temp_count;
return a;
}
int E_AddSub(){
int t1;
int rtn=T_MulDiv();
t1=rtn;
rtn=E1_AddSub(t1);
return rtn;
}
int E1_AddSub(int a){
int rtn,t1;
rtn=a;
if(expr[now_addr].cod==35||expr[now_addr].cod==36){
int op=expr[now_addr++].cod;
int opr2=T_MulDiv();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -