编译原理end

#include<bits/stdc++.h>
using namespace std;

const int max_word = 505;
//关键字 
const char keyWord[13][20] = {"main","if","else","do","while","for","switch",
"case","int","double","float","long","void"};

//单词表 
struct Word{
	char value[20];//单词值 
	int type;//单词种类
	int line;//行号 
}w[max_word]; 

//四元式
struct si_Yuan{
	string op;//运算符
	string s1;
	string s2;
	string res;//结果 
}sy[105];
//文件流 
FILE *fin,*fout;
int line = 1;
char token[12];//存放单词 
int flag = 0;//判断是否获取字符 
int flag1 = 0,flag2;//flag1判断是否项已经产生miss错误; 
int e = 0;//错误个数 
int sy_num = 0;//四元式的个数
string op,s1,ss1,s2,res,res1,res2,op2,op1; 
int op_num = 0,op_num1 = 0;//运算符的个数
int sy_id;//四元式的序号 

string var[300];//已经声明的变量 
int var_num = 0;//声明变量的个数 

int sent_id;//判断if,while语句 
string equ[300];//= 
int a,b,c; 
int equ_num = 1; //=个数 
int cnt = 0,token_num = 0;//当前字符 
int row = 1;//当前行数 
char ch;
char ch1; 

int word_num = 0;//单词的总个数 
int word_cnt = 0;
string temp;
char str_int[20];
stack<string>word_stack;//保存 
stack<string>op_stack;
//程序 
void S();
void P();//(){分程序} 
void P1();//分程序 
void A();//变量说明部分
void B();//语句部分
void B1();
int C();//变量说明
void D();//标识符表
void D1();
void E();//标识符
void F();//字母 
void G();//数字 
void H();//语句 
void I();//赋值语句 
void J();//条件语句 
void K();//循环语句 
int L();//关系运算符 
void M();//表达式 
void M1();
void N();//项 
void N1();
int O();//加法运算符 
int Q();//乘法运算符 
void R();//常量 
void S();//无符号整数 
void T();//数字序列 
void W();//复合语句 
void X();//条件 
void Y();//语句1 
void Z();//因子
 
//构造四元式 
void siYuan(string op,string s1,string s2,string res)
{	
	sy[sy_num].op =op;
	sy[sy_num].s1=s1;
	sy[sy_num].s2=s2;
	sy[sy_num].res=res;
	sy_num++;
}

void printFour()//输出四元式 
{
	ofstream out("sy.txt");
    int i;
    for(i=0;i<sy_num;i++)
   	{
   		cout<<i<<":\t("<<sy[i].op<<",\t"<<sy[i].s1<<",\t"<<sy[i].s2<<",\t"<<sy[i].res<<")"<<endl;
   		out<<i<<":\t("<<sy[i].op<<",\t"<<sy[i].s1<<",\t"<<sy[i].s2<<",\t"<<sy[i].res<<")"<<endl;
    }
}
void error(string err)//报错,定位到错误行 
{
        cout<<"第"<<w[word_cnt].line<<"行出错!\t";
		cout<<err<<"\n";
		e++;
}

//检查变量是否被声明
void is_say(string a)
{
	int i;
    for(i=1;i<=var_num;i++)
    {
    	if(a.compare(var[i])==0)
		{
			break;
		}
	}
	if(i>var_num)  
	{
		cout<<"第 "<<w[word_cnt].line<<" 行出错!\t";
		cout<<w[word_cnt].value<<" 没有被声明 !"<<endl;
		e++;
	}
}

void init_token(){
	int i;
	for(i = 0;i < 12;i++){
		token[i] = NULL;
	}
}

int judge_token(){
	init_token();
	if(flag == 0){
		ch = getc(fin);
	}
	flag = 1;
	while(ch == ' ' || ch == '\t' || ch == '\n'){
		if(ch == '\n'){
			row++;
		}
		ch=getc(fin);
	}
	token_num = 0;
	if((ch>='a' && ch <= 'z') || (ch >= 'A' &&ch <= 'Z')){
		//可能为标识符或者变量名 
		while((ch>='a' && ch <= 'z') || (ch >= 'A' &&ch <= 'Z') || (ch >= '0' && ch <= '9')){
			token[token_num++] = ch;
			ch = getc(fin);
		}
		token[token_num++] = '\0';
		for(int i = 0;i <13;i++){
			if(strcmp(token,keyWord[i]) == 0){
				//3为关键词 
				return 3;
			}
		}
		//2为标识符 
		return 2;
	}
	//是数字 
	else if(ch >= '0' && ch <= '9'){
		while((ch >= '0'&& ch <= '9') || ch == '.'){
			token[token_num++] = ch;
			ch = getc(fin);
		}
		return 1;
	}
	else{
		token[token_num++] = ch;
		switch(ch){
			case '(': ch = getc(fin); return 16;
			case ')': ch = getc(fin); return 17;
			case '{': ch = getc(fin); return 33;
			case '}': ch = getc(fin); return 34;
			case '+':
				ch = getc(fin);
				if(ch == '+'){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 29;
				}
				else{
					return 18;
				}
			case '-':
				ch = getc(fin);
				if(ch == '-'){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 30;
				}
				else{
					return 19;
				}
			case '*':
				ch = getc(fin);
				if(ch == '/'){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 32;
				}
				else{
					return 20;
				}
			case '/':
				ch = getc(fin);
				if(ch == '*'){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 31;
				}
				else{ 
					return 21;
				}
			//这里要重新编码 
			case '=':
				ch = getc(fin);
				if(ch == '='){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 23;
				}
				else{
					return 22;
				}
			case '>':
				ch = getc(fin);
				if(ch == '='){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 24;
				}
				else{
					return 23;
				}
			case '<':
				ch = getc(fin);
				if(ch == '='){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 26;
				}
				else{
					return 25;
				}
			case ';': ch = getc(fin); return 27;
			case '"': ch = getc(fin); return 28;
			case '!':
				ch = getc(fin);
				if(ch == '='){
					token[token_num++] = ch;
					ch = getc(fin); 
					return 37;
				}
				else{
					return 36;
				}
			case '#': ch = getc(fin); return -2;
			case ',': ch = getc(fin); return 35;
			case EOF: return -1;
			default: ch = getc(fin); return -10;
		}
	}
}

void getWord(){
	int temp;
	while(1){
		temp = judge_token();
		if(temp==-1){
			break;
		}
		switch(temp){
			case -10:
				//cout<<"第 "<<row<<" 行出现错误."<<endl;
				error("word has a mistake");
				w[word_num].type = -1;
				strcat(w[word_num].value," ");
				word_num++;
				break;
			case -1:
				return;
			default:
				w[word_num].type  = temp;
				w[word_num].line = row;
				strcpy(w[word_num].value,token);
				word_num++;
				//cout<<"<"<<temp<<","<<token<<">"<<endl;
				break;
		}
	}
}
//程序 
void S(){
	if(strcmp("main",w[word_cnt].value)){
		error("miss main");
		word_cnt--;
	}
	word_cnt++;
	if(strcmp("(",w[word_cnt].value)){
		error("miss (");
		word_cnt--;
	}
	word_cnt++;
	if(strcmp(")",w[word_cnt].value)){
		error("miss )");
		word_cnt--;
	}
	word_cnt++;
	if(strcmp("{",w[word_cnt].value)){
		error("miss {");
		word_cnt--;
	}
	word_cnt++;
	P();
	if(strcmp("}",w[word_cnt].value)){
		error("miss }");
		word_cnt--;
	}
	op = "#";
	s1 = "";
	s2 = "";
	res = "";
	siYuan(op,s1,s2,res);
	cout<<"There are "<<e<<" mistakes in total."<<endl;
}
//分程序 
void P(){
	A();//变量说明部分
	if(strcmp(";",w[word_cnt].value)){
		error("miss ;");
		word_cnt--;
	}
	word_cnt++;
	B();//语句部分 
}
//变量说明部分 
void A(){
	if(C()){
		var[++var_num] = w[word_cnt].value;
		D();
	}
	else{
		D();
	}
}
//变量说明 
int C(){
	if(strcmp(w[word_cnt].value,"int")){
		error("miss int");
		return 0;
	}
	word_cnt++;
	return 1;
}
//标识符表
void D(){
	if(w[word_cnt].type != 2){
		error("denoter has a error");
	}
	word_cnt++;
	D1();
}
//子标识符表 
void D1(){
	if(strcmp(w[word_cnt].value,";") == 0){
		return;
	}
	if(strcmp(w[word_cnt].value,",")){
		error("miss ,");
		word_cnt--;
	}
	word_cnt++;
	var[++var_num] = w[word_cnt].value;
	if(w[word_cnt].type!=2){
		error("denoter has a error");
	}
	word_cnt++;
	D1();
}
//语句部分 
void B(){
	H();
	B1();
}
//子语句部分 
void B1(){
	if(strcmp(w[word_cnt].value,";") == 0){
		word_cnt++;
		H();
		B1();
	}
	else if(strcmp(w[word_cnt].value,"}") == 0){
		return;
	}
	else{
		error("miss ;");
	}
}
//语句 
void H(){
	cout<<"H()"<<endl;
	cout<<w[word_cnt].value<<endl;
	if(w[word_cnt].type == 2){
		op_num = 0;
		is_say(w[word_cnt].value);
		word_stack.push(w[word_cnt].value);
		word_cnt++;
		I();
	}
	else if(strcmp(w[word_cnt].value,"if") == 0){
		op_num = 0;
		J();
	}
	else if(strcmp(w[word_cnt].value,"while") == 0){
		op_num = 0;
		a = sy_num;
		K();
		op = "go";
		s1 = "";
		s2 = "";
		stringstream sss;//int 转 string 
		sss<<a;
		sss>>res;
		siYuan(op,s1,s2,res);
		//修改while跳转的序号
		stringstream sss2;
		sss2<<sy_num;
		sss2>>sy[sent_id].res;
	}
	else{
		error("extra fuhao"); 
	}
}

//赋值语句
void I(){
	if(strcmp(w[word_cnt].value,"=") == 0){
		word_cnt++;
		//word_stack.push(w[word_cnt].value); 
		M();
		if(e > 0){
			return;
		}
		if(op_stack.size() > 0){
			op = op_stack.top();
			op_stack.pop();
			s2 = word_stack.top();
			word_stack.pop();
			s1 = word_stack.top();
			word_stack.pop();
			res = word_stack.top();
			word_stack.pop();
			siYuan(op,s1,s2,res);
		}
		else{
			s1 = word_stack.top();
			word_stack.pop();
			res = word_stack.top();
			word_stack.pop();
			siYuan("=",s1,"",res);
		}
		
	}
	else{
		error("miss = ");
		word_cnt--; 
	}
} 
//if语句 
void J(){
	cout<<"J()"<<endl;
	if(strcmp(w[word_cnt].value,"if")){
		error("miss if");
		word_cnt--;		
	}
	word_cnt++;
	if(strcmp(w[word_cnt].value,"(")){
		error("miss (");
		word_cnt--;
	}
	word_cnt++; 
	//word_stack.push(w[word_cnt].value);
	X();//条件 
	sent_id = sy_num;
	if(op_stack.size() > 0 && e == 0){
		op = op_stack.top();
		op_stack.pop();
		s2 = word_stack.top();
		word_stack.pop();
		s1 = word_stack.top();
		word_stack.pop();
		siYuan(op,s1,s2,res);
	}
	if(strcmp(w[word_cnt].value,")")){
		error("miss )");
		word_cnt--;
	}
	word_cnt++;
	//四元式置为空
	op = "";
	s1 = "";
	s2 = "";
	res = "";
	Y();//语句1
	
	stringstream ss;
	ss<<sy_num+1;
	ss>>sy[sent_id].res;
		
	sent_id = sy_num;
	op = "go";
	s1 = "";
	s2 = "";
	res = "";
	siYuan(op,s1,s2,res);
	if(strcmp(w[word_cnt].value,"else")){
		error("miss else");
		word_cnt--;
	}
	word_cnt++;
	Y();
	stringstream ss2;
	ss2<<sy_num;
	ss2>>sy[sent_id].res;
}

//while语句
void K(){
	cout<<"K()"<<endl;
	if(strcmp(w[word_cnt].value,"while")){
		error("miss while");
		word_cnt--;
	}
	word_cnt++;
	if(strcmp(w[word_cnt].value,"(")){
		error("miss (");
		word_cnt--;
	}
	word_cnt++;
	//word_stack.push(w[word_cnt].value);
	X();
	sent_id = sy_num;
	
	if(op_stack.size()>0 && e == 0){
		op = op_stack.top();
		op_stack.pop();
		s2 = word_stack.top();
		word_stack.pop();
		s1 = word_stack.top();
		word_stack.pop();
		siYuan(op,s1,s2,res);
	}
	
	//cout<<w[word_cnt].value<<endl;
	if(strcmp(w[word_cnt].value,")")){
		error("miss )");
		word_cnt--;
	}
	word_cnt++;
	if(strcmp(w[word_cnt].value,"do")){
		error("miss do");
		word_cnt--;
	}
	word_cnt++;
	Y();	
}
 
void X(){
	cout<<"X()"<<endl;
	M();

	if(op_stack.size() > 0 && e == 0){
		op = op_stack.top();
		op_stack.pop(); 
		s2 = word_stack.top();
		word_stack.pop(); 
		s1 = word_stack.top();
		word_stack.pop();
		stringstream ss;
		ss << op_num;
		res = "t"+ss.str();
		word_stack.push(res);
		siYuan(op,s1,s2,res);
	}
	

	if(strcmp(w[word_cnt].value,">") == 0){
		op = "<=";
	}
	else if(strcmp(w[word_cnt].value,">=") == 0){
		op = "<";
	}
	else if(strcmp(w[word_cnt].value,"<") == 0){
		op = ">=";
	}
	else if(strcmp(w[word_cnt].value,"<=") == 0){
		op = ">";
	}
	else if(strcmp(w[word_cnt].value,"==") == 0){
		op = "!=";
	}
	else if(strcmp(w[word_cnt].value,"!=") == 0){
		op = "==";
	}
	//cout<<w.value<<"  "<<w.type<<endl;
	if(!L()){
		error("miss relation operator");
		word_cnt--;
	}
	op_stack.push(op);
	word_cnt++;
	//word_stack.push(w[word_cnt].value);
	//sent_id = sy_num;
	M();
}
//表达式 
void M(){
	cout<<"M()"<<endl;
	N();
	M1();
}
//子表达式 
void M1(){
	cout<<"M1()"<<endl;
	cout<<w[word_cnt].value<<endl;
	if(strcmp(w[word_cnt].value,";") == 0 || strcmp(w[word_cnt].value,")") == 0 
	|| L() || strcmp(w[word_cnt].value,"}") == 0 || strcmp(w[word_cnt].value,"else") == 0){
		return;
	}
	else if(!O()){
		error("miss + or -");
		//word_cnt--;
	}
	else{
		op_stack.push(w[word_cnt].value);
		word_cnt++;
		//word_stack.push(w[word_cnt].value);
		op_num++; 
		//getWord();
		//strcpy(b[b_num++].bds,new_w.value);
		N();
		M1();

		if(op_stack.size() > 1 && e == 0){
			op = op_stack.top();
			op_stack.pop();
			s2 = word_stack.top();
			word_stack.pop(); 
			s1 = word_stack.top();
			word_stack.pop();
			stringstream ss;
			ss << op_num;
			res = "t"+ss.str();
			word_stack.push(res);
			siYuan(op,s1,s2,res);
		}
		
	}
}

//项 ,消除左递归 
void N(){
	cout<<"N()"<<endl;
	Z();
	N1();
}
void N1(){
	cout<<"N1()"<<endl;
	cout<<w[word_cnt].value<<endl;
	//后根符号集,关系运算符  ;  ) 
	if(strcmp(w[word_cnt].value,";") == 0 || strcmp(w[word_cnt].value,")") == 0 
	|| strcmp(w[word_cnt].value,"}") == 0 || strcmp(w[word_cnt].value,"else") == 0 || L() || O()){
		return;
	}
	else if(!Q()){
		error("miss * or /");
		//分号出错转到语句 
		//word_cnt--;
	}
	//word_cnt++;
	else{
		op_num++;
		op_stack.push(w[word_cnt].value);
		word_cnt++;
		//word_stack.push(w[word_cnt].value);
		Z();
		N1();
		
		if(op_stack.size() > 1 && e == 0){
			op = op_stack.top();
			op_stack.pop();
			s2 = word_stack.top();
			word_stack.pop(); 
			s1 = word_stack.top();
			word_stack.pop();
			stringstream ss;
			ss << op_num;
			res = "t"+ss.str();
			word_stack.push(res);
			siYuan(op,s1,s2,res);
		}
		
	}
}
//因子
void Z(){
	//cout<<w.value<<"  "<<w.type<<endl;
	//非数字或标识符 
	cout<<"Z()"<<endl;
	if(w[word_cnt].type!=1 && w[word_cnt].type!=2 &&strcmp(w[word_cnt].value,"(")){
		error("expression has a error");
		return;
	}
	//标识符
	if(w[word_cnt].type == 1||w[word_cnt].type == 2){
		if(w[word_cnt].type == 2){
			is_say(w[word_cnt].value);
		}
		word_stack.push(w[word_cnt].value);
		word_cnt++;
		//equ[equ_num++] = w.value;
		return;
	}
	else if(strcmp(w[word_cnt].value,"(") == 0){
		word_cnt++;
		//word_stack.push(w[word_cnt].value);
		M();
		if(e == 0){
			op = op_stack.top();
			op_stack.pop();
			s2 = word_stack.top();
			word_stack.pop(); 
			s1 = word_stack.top();
			word_stack.pop();
			stringstream ss;
			ss << op_num;
			res = "t"+ss.str();
			word_stack.push(res);
			siYuan(op,s1,s2,res);
		}
		
		if(strcmp(w[word_cnt].value,")") == 0){
			word_cnt++;
			return;
		}
		else{
			error("miss )");
		}
	}
	return;
}

//语句1 
void Y(){
	cout<<"Y()"<<endl; 
	if(strcmp(w[word_cnt].value,"{") == 0){
		word_cnt++;
		B();
		//cout<<w.value<<endl;
		if(strcmp(w[word_cnt].value,"}")){
			error("miss }");
		}
		word_cnt++;
		return; 
	}
	else{
		H();//语句
		return; 
	}
}

//关系运算符
int L(){
	if(((w[word_cnt].type > 22 && w[word_cnt].type <= 26) || w[word_cnt].type == 37)){
		return 1;
	}
	return 0;
} 

//加法运算符 
int O(){
	if(w[word_cnt].type == 18 || w[word_cnt].type == 19){
		return 1;
	}
	return 0;
}
//乘法运算符 
int Q(){
	if(w[word_cnt].type == 20 || w[word_cnt].type == 21){
		return 1;
	}
	return 0;
}

int main(){
	fin = fopen("compiler.txt","r");
	getWord();
	S();
	if(e==0)
	{
		printFour();
	}
	else
	{
		cout<<"\nSorry,can not generate siYuan."<<endl;
	}
	return 0;
}
/*

*/

 

兔兔RabbitMQ!!! CSDN认证博客专家 Go/GoLang Redis MySQL
全站最硬核博主(之一)。在腾讯总部工作,bat/tmd有五家发过offer。acm/leetcode刷题狂,c /Java/python/go/php各种后端语言都喜欢,安卓/node/叶子/jsp等前端也能写,最喜欢鼓捣各种组件,请多指教。
已标记关键词 清除标记
附录c 编译程序实验 实验目的:用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。 语法分析 C2.1 实验目的 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析. C2.2 实验要求 利用C语言编制递归下降分析程序,并对简单语言进行语法分析. C2.2.1待分析的简单语言的语法 实验目的 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法. 实验要求 采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。 实验的输入和输出 输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。 例如:对于语句串 begin a:=2+3*4;x:=(a+b)/c end# 输出的三地址指令如下: (1) t1=3*4 (2) t2=2+t1 (3) a=t2 (4) t3=a+b (5) t4=t3/c (6) x=t4 算法思想 1设置语义过程 (1) emit(char *result,char *arg1,char *op,char *ag2) 该函数功能是生成一个三地址语句送到四元式表中。 四元式表的结构如下: struct {char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20]; (2)char *newtemp() 该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…. Char *newtemp(void) { char *p; char m[8]; p=(char *)malloc(8); k++; itoa(k,m,10); strcpy(p+1,m); p[0]=’t’; return(p); } (2)主程序示意图如图c.10所示。 (2) 函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。 语义分析程序的C语言程序框架 int lrparser() { int schain=0; kk=0; if(syn=1) { 读下一个单词符号; schain=yucu; /调用语句串分析函数进行分析/ if(syn=6) { 读下一个单词符号; if(syn=0 && (kk==0)) 输出(“success”); } else { if(kk!=1 ) 输出 ‘缺end’ 错误;kk=1;} else{输出’begin’错误;kk=1;} } return(schain); int yucu() { int schain=0; schain=statement();/调用语句分析函数进行分析/ while(syn=26) {读下一个单词符号; schain=statement(); /调用语句分析函数进行分析/ } return(schain); } int statement() { char tt[8],eplace[8]; int schain=0; {switch(syn) {case 10: strcpy(tt,token); scanner(); if(syn=18) {读下一个单词符号; strcpy(eplace,expression()); emit(tt,eplace,””,””); schain=0; } else {输出’缺少赋值号’的错误;kk=1; } return(schain); break; } } char *expression(void) {char *tp,*ep2,*eplace,*tt; tp=(char *)malloc(12);/分配空间/ ep2=(char *)malloc(12); eplace=(char *)malloc(12); tt =(char )malloc(12); strcpy(eplace,term ());/调用term分析产生表达式计算的第一项eplace/ while(syn=13 or 14) { 操作符 tt= ‘+’或者‘—’; 读下一个单词符号; strcpy(ep2,term());/调用term分析产生表达式计算的第二项ep2/ strcpy(tp,newtemp());/调用newtemp产生临时变量tp存储计算结果/ emit(tp,eplace,tt,ep2);/生成四元式送入四元式表/ strcpy(eplace,tp); } return(eplace); } char *term(void)/仿照函数expression编写/ char *factor(void) {char *fplace; fplace=(char *)malloc(12); strcpy(fplace, “ ”); if(syn=10) {strcpy(fplace,,token);/将标识符token的值赋给fplace/ 读下一个单词符号; } else if(syn=11) {itoa(sum,fplace,10); 读下一个单词符号; } else if (syn=27) {读下一个单词符号; fplace=expression();/调用expression分析返回表达式的值/ if(syn=28) 读下一个单词符号; else{输出‘}’错误;kk=1; } } else{输出‘(’错误;kk=1; } return(fplace); }
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页