所有的源码都放GitHub了:https://github.com/yuyi5453/Compilation-principle
语法树是递进形式,至于树的形式再想想,不太好写。
版本一是函数调用的的时候直接输出的,版本二是建了棵树。至于老师说的栈什么的没太听清楚。
词法分析当成头文件用了。
拿set处理了未声明和重复声明。其他的还没写
(两个版本都有一个隐藏的的小bug,希望老师查不到吧hhhh)
版本一:函数调用和输出符号的时候递进地输出每一个节点
#include<bits/stdc++.h>
#include"DSJ_词法分析.h"
using namespace std;
char token[20],token1[40];
char yufa_in[300];//词法分析文件名
char yufa_out[300];
FILE *fin,*fout;
set<string>se;
int program(int p);
int declaration_list(int p);
int declaration_stat(int p);
int statement_list(int p);
int statement(int p);
int if_stat(int p);
int while_stat(int p);
int for_stat(int p);
int read_stat(int p);
int write_stat(int p);
int compound_stat(int p);
int expression_stat(int p);
int expression(int p);
int bool_expr(int p);
int additive_expr(int p);
int term(int p);
int factor(int p);
int fun_declaration(int p);//
int fun_body(int p);//
int main_declaration(int p);//
int call_stat(int p);//
void shift(int p){
for(int i=0;i<p;i++) fprintf(fout," ");
}
void out(int p){
shift(p+1);
fprintf(fout,"%s\n",token1);
}
int TESTparse(){
int es=0;
strcpy(yufa_in,cifa_out);
if((fin=fopen(yufa_in,"r"))==NULL){
printf("打开%s文件错误\n",yufa_in);
es=10;
}
strcpy(yufa_out,"out_yufa_");
strcat(yufa_out,cifa_in);
if((fout=fopen(yufa_out,"w"))==NULL){
printf("打开yufa_out文件错误\n");
es=10;
}
if(es==0) es=program(0);
printf("=====语法分析结果:======\n");
switch(es){
case 0:printf("语法分析成功\n");break;
case 10:cout<<"打开输入文件失败"<<endl;break;
case 1:cout<<"缺少{!"<<endl;break;
case 2:cout<<"缺少}!"<<endl;break;
case 3:cout<<"缺少标识符!"<<endl;break;
case 4:cout<<"缺少分号!"<<endl;break;
case 5:cout<<"缺少(!" <<endl;break;
case 6:cout<<"缺少)!"<<endl;break;
case 7:cout<<"缺少操作数!"<<endl;break;
case 8:cout<<"重复定义!"<<endl;break;
case 9:cout<<"缺少main函数"<<endl;break;
case 11:cout<<"非法声明,缺少fun/main"<<endl;break;
case 12:cout<<"使用未声明变量!"<<endl;break;
default: cout<<es<<endl;
}
fclose(fin);
fclose(fout);
return es;
}
int program(int p){
shift(p);
fprintf(fout,"<program>\n");
int es=0;
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,"function")&&strcmp(token,"main")){
return es=11;
}
while(strcmp(token,"function")==0){
es=fun_declaration(p+1);
if(es>0) return es;
}
if(strcmp(token,"main")){
return es=9;
}
es=main_declaration(p+1);
if(es>0) return es;
return es;
}
int fun_declaration(int p){
shift(p);
fprintf(fout,"<fun_declaration>\n");
out(p);
int es=0;
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,"ID")) return es=3;
out(p);
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,"(")) return es=5;
out(p);
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,")")) return es=5;
out(p);
es=fun_body(p+1);
if(es>0) return es;
return es;
}
int main_declaration(int p){
shift(p);
fprintf(fout,"<main_declaration>\n");
out(p);
int es=0;
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,"(")) return es=5;
out(p);
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,")")) return es=6;
out(p);
es=fun_body(p+1);
if(es>0) return es;
fscanf(fin,"%s %s\n",token,token1);
return es;
}
int fun_body(int p){
shift(p);
fprintf(fout,"<fun_body>\n");
int es=0;
fscanf(fin,"%s %s\n",token,token1);
if(strcmp(token,"{")) return es=1;
out(p);
fscanf(fin,"%s %s\n",token,token1);
es=declaration_list(p+1);
if(es>0) return es;
es=statement_list(p+1);
if(es>0) return es;
if(strcmp(token,"}")) return es=2;
out(p);
fscanf(fin,"%s %s\n",token,token1);
se.clear();//清空一个识别完成的函数体内的变量
return es;
}
int declaration_list(int p){
shift(p);
fprintf(fout,"<declaration_list>\n");
int es=0;
while(strcmp(token,"int")==0){
es=declaration_stat(p+1);
if(es>0) return es;
}
return es;
}
int declaration_stat(int p){
shift(p);
fprintf(fout,"<declaration_stat>\n");
int es=0;
out(p);
fscanf(fin,"%s %s\n",token,token1);
// printf("%s %s\n",token,token1);
if(strcmp(token,"ID")) return es=3;
if(se.count(token1)) return es=8;
se.insert(token1);
out(p);
fscanf(fin,"%s %s\n",token,token1);
// printf("%s %s\n",token,token1);
if(strcmp(token,";")) return es=4;
out(p);
fscanf(fin,"%s %s\n",token,token1);
// printf("%s %s\n",token,token1);
return es;
}
int statement_list(int p){
shift(p);
fprintf(fout,"<statement_list>\n");
int es=0;
while(strcmp(token,"}")){
es=statement(p+1);
if(es>0) return es;
}
return es;
}
int statement(int p){
shift(p);
fprintf(fout,"<statement>\n");
int es=0;
if(es==0&&strcmp(token,"if")==0) es=if_stat(p+1);
if(es==0&