编译原理实验 语法分析 树状语法树输出

本文分享了一次编译原理实验,重点介绍了语法分析过程,并展示了如何生成树状语法树。源代码已上传至GitHub,供读者参考。
摘要由CSDN通过智能技术生成

所有的源码都放GitHub了:https://github.com/yuyi5453/Compilation-principle

 

成品图:

源码

#include<bits/stdc++.h>
#include"DSJ_词法分析.h"
using namespace std;
const int max_len=11;
char token[20],token1[40];
char yufa_in[300];//词法分析文件名
char yufa_out[300];
char tree_map[100][1000];
FILE *fin,*fout;
set<string>se;
struct node{
	string st;
	vector<node*>son;
	int cnt; 
	node* addSon(string s){
		node* Son=new node();
		Son->st=s;
		son.push_back(Son);
		return Son;
	}
} *Root; 
int program();
int declaration_list(node* fa);
int declaration_stat(node* fa);
int statement_list(node* fa);
int statement(node* fa);
int if_stat(node* fa);
int while_stat(node* fa);
int for_stat(node* fa);
int read_stat(node* fa);
int write_stat(node* fa);
int compound_stat(node* fa);
int expression_stat(node* fa);
int expression(node* fa);
int bool_expr(node* fa);
int additive_expr(node* fa);
int term(node* fa);
int factor(node* fa);
int fun_declaration(node* fa);//
int fun_body(node* fa);//
int main_declaration(node* fa);//
int call_stat(node* fa);//
void out(node* p){
	p->addSon(token1);
}
void shift(int x){
	for(int i=0;i<x;i++) fprintf(fout," ");
}
void draw_line(int x,int y1,int y2){
	for(int i=y1+1;i<y2;i++) tree_map[x][i]='-';
} 
void string_out(int x,int y,string s){
	int l=y-5;
	int len=s.length();
	int space=(max_len-len)/2;
	for(int i=0;i<space;i++) tree_map[x][l++]=' ';
	for(int i=0;i<len;i++) 
		tree_map[x][l++]=s[i];
	
	for(int i=0;i<max_len-len-space;i++) tree_map[x][l++]=' '; 
}
void tree_out(int x,int y,node* p){
	string_out(x,y,p->st);
	int num=p->son.size();//子树个数
	if(num==0) return ;
	tree_map[x+1][y]='|';
	int len=p->cnt;//子树宽度
	int pos[num];//子树位置
	pos[0]=y-len*11/2+p->son[0]->cnt*11/2;
	for(int i=1;i<num;i++){
		pos[i]=pos[i-1]+(p->son[i-1]->cnt+p->son[i]->cnt)/2*11+1;
	}
	draw_line(x+2,pos[0],pos[num-1]);
	for(int i=0;i<num;i++){
		tree_map[x+3][pos[i]]='|';
		tree_out(x+4,pos[i],p->son[i]);
	}
	return ;
}

int tree_cnt(node *p){
	int nc=p->son.size();
	if(nc==0){
		p->cnt=1;
		return 1;
	} 
	int sum=0;
	for(int i=0;i<nc;i++){
		sum+=tree_cnt(p->son[i]);
	}
	p->cnt=sum;
	return sum;
}
void print_tree(){
	for(int i=0;i<100;i++){
		for(int j=0;j<1000;j++){
			if(tree_map==0) fprintf(fout," ");
			else fprintf(fout,"%c",tree_map[i][j]);
		}
		fprintf(fout,"\n");
	}
}
//void print_tree(){
//	for(int i=0;i<100;i++){
//		for(int j=0;j<1000;j++){
//			if(tree_map==0) printf(" ");
//			else printf("%c",tree_map[i][j]);
//		}
//		printf("\n");
//	}
//}
int TESTpar
编译原理实验中的PL/0语言(Programming Language One)是一种教学语言,主要用于帮助学生理解编译器的各个阶段,包括词法分析、语法分析、语义分析等。在PL/0语义分析阶段,主要目标是将源代码解析成一个形式化的表示,以便后续阶段能够处理和优化。 **语义分析**(Semantic Analysis): - PL/0的语义分析通常涉及到检查程序是否遵循了语言的语法规则,并赋予每个符号或表达式实际的意义。这涉及到类型检查、作用域查找、变量绑定等任务。 - 该阶段生成的是一个中间代码(Intermediate Representation, IR),如三地址码(Three-address code),这是编译器中的一个重要环节,它使代码更易于理解和优化。 **抽象语法树**(Abstract Syntax Tree, AST): - 抽象语法树是PL/0语义分析后的结果之一。它是一个树状结构,每个节点代表源代码的一个语法结构,如程序块、变量声明、运算符等。 - 每个节点包含了相应的语义信息,比如操作数、变量类型、函数调用等,而非直接的文本字符。 - AST有助于表达程序的结构,便于进一步的分析(如控制流分析)、优化(如常量折叠、死代码消除)以及代码生成。 相关问题: 1. PL/0语义分析的主要任务是什么? 2. 在PL/0中,抽象语法树如何体现程序的结构? 3. 从AST到中间代码的转换过程中,可能涉及哪些优化技术?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值