⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 micro( ok 07.6.27基本完成).cpp

📁 微小语言编辑器的代码 虽然简单但是LINUX都是由MINIX来的 这也算是启发之源了
💻 CPP
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////
//Micro 编译器前端
//辽宁科技大学
//计算机科学与工程学院
//计算机科学与技术 05 级2班 
//刘世安
/////////////////////////////////////////
#include <iostream.h>
#include <stdlib.h>//atoi() atol()
#include <fstream.h>
#include <string.h>
struct FormStruct//变量属性结构体
{
	char varName[10];
	char varType[10];
	
};
struct PostfixStruct//后缀式存储表
{
	char  N_Str[10];//变量名
	char C_Str[10];//变量类型
	float R_Num;
	int   Z_Num;
};
struct  PivotalStruct//关键字结构
{
	char name[10];
	char Outname[10];
	int flag;
};
PivotalStruct guanjian[]={//初始化关键字
	{"begin","$begin",1},
	{"var","$var",2},
	{"integer","$integer",5},
	{"real","$real",5},
	{"read","$read",9},
	{"end","$end",11},
	{"write","$write",10}};

	class MicroComPile
	{
	private:
		ifstream infile;
		ofstream outfile;
		char letter;
		char thisWord[10];
		float number;
		int arraySign;
		int numOfLine;
		int flag;
		bool numflag;
		int err;
		int warn;
		int numOfEnter;
		FormStruct varForm[20];//符号表
		char *SourceFile;//保存文件 
		int Ecount;
		PostfixStruct express[10];//后缀式存储空间
		
	public:
		MicroComPile(char *filename);
		~MicroComPile();
		void Read();
		void NoBlank();//删除空格
		void Append();
		void Parser();//语法分析
		void Identifier();
		void Error(int n);//
		void Match(int n,int m);//
		void Expr();//
		
		bool isLetter();//letter是字母
		bool isDigit();//letter是数字
		void Scanner();//词法分析
		
		
		void DisplayResult();
		void ReadConstant();//处理常数 
		void Semantic();//语义分析实现 
		void ExprSemantic();//语义分析实现使用
		int varTest();//功能:检测变量是否有声明
		void  ErrOfSemantic(int n);
		char* newadress(int n);//产生临时变量名
		void disvarForm();//显示表格内容
		void disbiao();
		char* ProduceMiddleP();//中间代码生成
	};
	MicroComPile::MicroComPile(char *filename)
	{   
		err=0;//为Error()初始化err; 
		warn=0;//为Scanner()初始化warn; 
		numOfEnter=1;
		numOfLine=1;
		
		
		
		infile.open(filename);
		if(infile.fail())
		{
			cout<<"input.txt open fail \n";
			exit(1);
		}
		infile.seekg(0,ios::end); 
		//   读指针移到文件尾   
		int  FileSize= infile.tellg();  
		//  取文件大小, 
		
		SourceFile=new char[FileSize+1];
		//动态声请内存 
		infile.seekg(0,   ios::beg); 
		//   读指针移到文件头  
		arraySign=0;//初始化i; 
		while(!infile.eof())
		{
			SourceFile[arraySign]=infile.get();
			arraySign++;
		} 
		arraySign=0;//再次为Read()初始化i; 
		infile.close();
		/////////////////////////////	
		outfile.open("output.txt");
		if(outfile.fail())
		{
			cout<<"output.txt  open fail n";
			exit(1);
		}
		
		
	}
	MicroComPile::~MicroComPile()
	{
		outfile.close();
	}
	void MicroComPile::Read()
	{     
		letter=SourceFile[arraySign];
		arraySign++;
		numOfLine++;
	}
	void MicroComPile::DisplayResult()
	{
		cout<<"\n共"<<warn<<"个警告(词法分析)\n";
		cout<<"共"<<err<<"个错误(语法语义分析)\n";	
	}
	
	void MicroComPile::NoBlank()
	{	
		while(letter==' ' || letter=='\n' ||
			letter=='\t')
		{
			if(letter=='\n')
			{
				numOfEnter++;
				numOfLine=0;
			}
			if(letter==' ')
				numOfLine--;	
			
			Read();	
		}
	}
	///////////////////////////////////////////////
	bool MicroComPile::isLetter()
	{
		if((letter>='a' && letter<='z') ||
			(letter>='A' && letter<='Z'))
			return true;
		else
			return false;
	}
	bool MicroComPile::isDigit()
	{
		if(letter>='0' && letter<='9')
			return true;
		else
			return false;
	}
	void MicroComPile::Append()
	{
		int len=strlen(thisWord);
		//求的已读到的字母个数,将本次读到的 单词加到未部 
		thisWord[len]=letter;
		len++;
		thisWord[len]='\0';
	}
	void MicroComPile::Identifier()  
	{
		
		for(int i=0;i<10;i++)//将上次的单词清掉 
			thisWord[i]='\0';
		while(isLetter() || isDigit())
		{
			Append();
			Read();  
		}//while的条件不符时退到 Scanner
		arraySign--;
		//当最后读到的不是字符时要重新读入并处理	
	}
	//若出现类似于 21str 这样的变量时当数字处理,
	//字母舍掉 
	
	void MicroComPile::ReadConstant()  
	{
		numflag=false;
		for(int i=0;i<10;i++)//将上次的单词清掉 
			thisWord[i]='\0';
		while( isDigit())
		{
			Append();
			Read();  
		}//while的条件不符时退到 Scanner
		if(letter=='.')
		{
			numflag=true;
			do
			{
				Append();
				Read();  
			}while(isDigit());
			arraySign--;
			//当最后读到的不是字符时要重新读入并处理
		}
		else
			arraySign--;
		//当最后读到的不是字符时要重新读入并处理	
	}
	
	
	
	void MicroComPile::Scanner()
	{
		
		
		
		Read();
		NoBlank();
		
		//去掉while((SourceFile[i]!='\0'))后程序结束的条件
		if(SourceFile[arraySign]==EOF)//6.14修改
		{
			flag=0;
			return;
		} 
		int b=0;
		if(isLetter())//是字母 
		{
			Identifier();//则到这里将其拼成单词 
			for(int i=0;guanjian[i].name[0];i++)
			{
				if(strcmp(thisWord,guanjian[i].name)!=0)
					continue;
				else
				{ 
					outfile<<guanjian[i].Outname<<endl;
					flag=guanjian[i].flag;
					
					b=1;//标记
					break;
				}
			}

          if(b==0) 
		  {	
			  outfile<<"($id,"<<thisWord<<")"<<endl;	
			  flag=3;
		  }

		}	
		else if(isDigit())//是数字 
		{	
			ReadConstant();
			
			if(numflag)
			{	
				outfile<<"($realC,"<<thisWord<<")"<<endl;
				flag=17;
			}
			else
			{
				outfile<<"($intC,"<<thisWord<<")"<<endl;
				flag=16;
			}
		}
		//以下都是符号的处理
		else if(letter=='(') //是符号输出相应的标志 
		{
			outfile<<"$Lparen"<<endl;
			flag=7;
		}
		else if(letter==')')
		{	
			outfile<<"$Rparen"<<endl;
			flag=8;
		}
		else if(letter=='+')
		{  
			outfile<<"$plus"<<endl;
			flag=15;
		}
		else if(letter=='*')
		{	
			outfile<<"$mult"<<endl;
			flag=14;
		}
		
		else if(letter==';')
		{   
			outfile<<"$semi"<<endl;
			flag=6;
		}
		else if(letter==':')
		{
			Read();//再向前看一个 
			if(letter=='=')
			{
				outfile<<"$assig"<<endl;
				flag=12;
			}//输出赋值标志。
			else
			{	
				outfile<<"$colon"<<endl;
				flag=4;//退到 while() 
				arraySign--;
				//当最后读到的不是字符时要重新读入并处理	
			}
		}
		else if(letter=='.')
			//文件正常结束时 返回到主函数 
		{
			outfile<<"$stop"<<endl;
			flag=13;  
		}
		else if(letter=='#')
		{	
			do//删除注释
			{
				Read();
				
				if(SourceFile[arraySign]=='\0')
				{
					cout<<"最后的#无对应的结束符\n";
					break;
				}
			}while(letter!='#');
			Scanner();//自调用
		}
		else//非法标点符号的处理 
		{ warn++;
		cout<<"第"<<numOfEnter<<"行 第"<<numOfLine
			<<"个标点符号: \""<<letter<<"\" 非法!\n";
		}
}

void MicroComPile::Error(int n)
{   err++;
cout<<"第"<<numOfEnter<<"行 第"<<numOfLine<<"个字符处: ";
switch(n)
{
case 1:cout<<"程序头不是begin"<<endl;break;
case 2:cout<<"变量声明头不是var"<<endl;break;
case 3:cout<<"var后面不是标识符"<<endl;break;
case 4:cout<<"var id后不是\":\""<<endl;break;
case 5:cout<<"var id后不是类型符"<<endl;break;
case 6:cout<<"变量声明后不是\";\""<<endl;break;
case 7:cout<<"write后不是\"(\""<<endl;break;
case 8:cout<<"write(E 后不是\")\""<<endl;break;
case 9:cout<<"read后不是\"(\""<<endl;break;
case 10:cout<<"read(后不是id"<<endl;break;
case 11:cout<<"read(id后不是\")\""<<endl;break;
case 12:cout<<"赋值语句左部不是\":=\""<<endl;break;
case 13:cout<<"语句头单词错"<<endl;break;
case 14:cout<<"程序结束符错"<<endl;break;
case 15:cout<<"语句后继符错"<<endl;break;
case 16:cout<<"缺\"(E)\"中的 闭括号"<<endl;break;
case 17:cout<<"17运算分量的后继符错"<<endl;break;
default:cout<<"决不出现的错误!!!"<<endl;
}
}

void MicroComPile::Expr()
{
	
	do{
		Scanner();
		//若条件成立,则再读一个单词,所以这里需要 Scanner()
		if(flag==3);//ID
		else if(flag==16||flag==17);//number
		else if(flag==7)//(
		{
			Expr();
			Scanner();
            if(flag!=8)
				Error(16);
		}
		else 
			Error(17);
		Scanner();
		
		
	}while(flag==14||flag==15);	//+or*时while 		
}

void MicroComPile::Match(int n,int m)
{
	Scanner();
    if(flag!=n)
		Error(m);
}

void MicroComPile::Parser()
{	
	Match(1,1);
	Match(2,2);
    do
	{
		Match(3,3);
		Match(4,4);
		Match(5,5);
		Match(6,6);
		Scanner();
	}while(flag==2);
	
	do
	{
		if(flag==10)//write
		{
			Match(7,7);//(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -