编译原理 TEST语言语法分析+输出语法树 C/C++

本文介绍了使用C/C++实现TEST语言的语法分析,并通过递进方式输出语法树。作者分享了两个版本的实现,版本一在函数调用时逐节点输出,版本二构建了完整的语法树。此外,利用set处理了未声明和重复声明的问题,但还存在一个小bug。源代码已上传至GitHub。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

所有的源码都放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&
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值