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

📄 pl0doc.cpp

📁 编译原理实践教程PL0语言编译程序源代码。参考书:清华大学出版社的《编译原理》作者吕映芝、张素琴等。 实现主要功能有:对使用PL0语言编写的程序进行词法分析
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if(sym==29){
		Advance();
		expression(lev,tx);// odd
	}
	else{
		expression(lev,tx);
		if(sym>=18 && sym<=22){// =、<、<=、>、>=、
			Advance();
			expression(lev,tx);
		}
		else if(sym==28){      // #
			Advance();
			expression(lev,tx);
		}
		else error(20);        //应该为关系运算符
	}
}
//项
void CPL0Doc::term(int lev, int tx)
{
	factor(lev,tx);
	while(sym==15 || sym==16){//'*'、'/'
		Advance();
		factor(lev,tx);
	}
}
//表达式
void CPL0Doc::expression(int lev, int tx)
{
	if(sym==13 || sym==14){//'+'、'-'
		Advance();
		term(lev,tx);
	}
	else term(lev,tx);
	while(sym==13 || sym==14){//'+'、'-'
		Advance();
		term(lev,tx);
	}
}
//出错处理
void CPL0Doc::error(int a)
{
	CString str="";
	total_err++;
	if(total_err<=500){
		int pos=total_err-1;
		all_err[pos].Empty();
		all_err[pos].Format("%d ",sym_line);
		str.Format("%d",InPoint.GetColumn());
		all_err[pos]+="行 "+str+"列: ";
		//错误符为变量名
		if(sym==888) all_err[pos]+=sym_name;
		//错误符为关键字
		else if(sym>=1 && sym<=KeywordTotal) all_err[pos]+=keyword[sym];
		all_err[pos]+=("   "+err[a]);
	}
}
//因子
void CPL0Doc::factor(int lev, int tx)
{
	if(sym==999) Advance();
	else if(sym==888){
		if((test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,VAR)))
			Advance();
		else if(test(sym_name,lev,tx,PRO)){
			error(21);//表达式内标识符属性不能是过程。
			Advance();
		}
		else{
			error(11);//变量未定义
			Advance();
		}
	}
	else if(sym==24){               //"("
		Advance();
		expression(lev,tx);
		if(sym==25) Advance(); //")"
		else error(22);        //少 ")"
	}
}
//增加 常量、变量、过程说明
bool CPL0Doc::enter(CString name,KIND kind,int level,int value,int address=0,int size=0)
{
	if(TX<500){
		table[TX].name=name;
		table[TX].kind=kind;
		table[TX].level=level;
		table[TX].value=value;
		table[TX].address=address;
		table[TX].size=size;
		TX++;
		return true;
	}
	return false;
}

bool CPL0Doc::test(CString n, int lev,int tx, KIND k)
{
	for(int i=0;i<tx;i++){
		if(!n.Compare(table[i].name))
			if(table[i].kind==k && table[i].level<lev) return true;
	}
	for(i;i<TX;i++){
		if(!n.Compare(table[i].name))
			if(table[i].kind==k && table[i].level==lev) return true;
	}
	return false;
}

bool CPL0Doc::test(CString n, int lev, int tx)
{
	for(int i=tx;i<TX;i++){
		if(!n.Compare(table[i].name))
			if(table[i].level==lev) return true;
	}
	return false;
}
//语法分析往前读
void CPL0Doc::Advance(int i)
{
	if(i==0) PreTEI=twoelement.head;
	else if(PreTEI!=NULL) PreTEI=PreTEI->next;
	if(PreTEI!=NULL){
		sym=PreTEI->sym;
		sym_line=PreTEI->line;
		if(sym==888) sym_name=defsymbol.OutputDefSymbol(PreTEI->val);
		else if(sym==999) sym_val=defconstant.OutputDefConstant(PreTEI->val);
	}
	else sym=100;
}
//语法分析
bool CPL0Doc::OnSyntaxAnalyze() 
{
	// TODO: Add your command handler code here
	bool flag = false;
	OnWordAnalyze();
	total_err=0;
	//TX=0;
	TX=1;
	Advance(0);

	program();

	CString result;
	if(total_err==0) 
	{
		result+="已经通过语法分析!";
		flag=true;
	}
	else 
		for(int i=0;i<total_err;i++) result+=(all_err[i]+(char)13+(char)10);

	CView* cv;
	POSITION p=GetFirstViewPosition();
	cv=GetNextView(p);
	cv->SetWindowText(result);
	return flag;
}
//词法分析
void CPL0Doc::OnWordAnalyze() 
{
	// TODO: Add your command handler code here
	TX=1;
	CIndex = 0;
	defconstant.Empty();  //置空常量表
	defsymbol.Empty();    //置空变量表
	twoelement.Empty();   //置空二元组表
	int i,j;
	CString current;

	char ch=GetChar(0);
	while(ch!=127)
	{
		if((ch>64 && ch<91)||(ch>96 && ch<123))
		{//ch为大小写字母
			current.Empty();
			sym_word=sym_column;
			current+=ch;
			ch=GetChar();
			while((ch>47 && ch<58)||(ch>64 && ch<91)||(ch>96 && ch<123))
			{
				current+=ch;
				ch=GetChar();
			}
			InPoint.SetColumn(sym_word);
			i=SearchKeyWord(current);
			if(i) twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//关键字
			else
			{
				i=defsymbol.Insert(current);
				twoelement.Insert(888,current,i,InPoint.GetRow(),InPoint.GetColumn());//用户自定义符号
			}
			continue;
		}
		//是数字
		if(ch>47 && ch<58)
		{
			sym_word=sym_column;
			j=ch-48;
			i=j;
			ch=GetChar();
			while(ch>47 && ch<58)
			{
				j=ch-48;
				i=(i*10+j);
				ch=GetChar();
			}
			InPoint.SetColumn(sym_word);
			j=defconstant.Insert(i);
			twoelement.Insert(999,"number",j,InPoint.GetRow(),InPoint.GetColumn());
			continue;
		}
		if(ch==58)
		{//  :
			sym_word=sym_column;//////////
			current.Empty();
			current+=ch;
			ch=GetChar();
			if(ch==61)
			{//  =
				current+=ch;
				InPoint.SetColumn(sym_word);
				i=SearchKeyWord(current);
				twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入 :=
				ch=GetChar();
				continue;

			}
			else break;
		}
		if(ch==61)
		{//  =
			sym_word=sym_column;//////////
			current.Empty();
			current+=ch;
			InPoint.SetColumn(sym_word);///////////
			i=SearchKeyWord(current);
			twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入 :=
			ch=GetChar();
			continue;
		}
		if(ch>39 && ch<47)
		{// (  )  *  +  ,  -  .  
			sym_word=sym_column;//////////
			current=ch;
			InPoint.SetColumn(sym_word);///////////
			i=SearchKeyWord(current);
			twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入(  )  *  +  ,  -  .  /
			ch=GetChar();
			continue;
		}
		if(ch==35)
		{//   #
			sym_word=sym_column;//////////
			current=ch;
			InPoint.SetColumn(sym_word);///////////
			i=SearchKeyWord(current);
			twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入#
			ch=GetChar();
			continue;
		}
		if(ch==59)
		{//   ;
			sym_word=sym_column;//////////
			current=ch;
			InPoint.SetColumn(sym_word);///////////
			i=SearchKeyWord(current);
			twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入 ;
			ch=GetChar();
			continue;
		}
		if(ch==60 || ch==62)
		{//   <、  >
			sym_word=sym_column;//////////
			current=ch;
			ch=GetChar();
			if(ch==61)
			{//   =			
				current+=ch;
				InPoint.SetColumn(sym_word);///////////
				i=SearchKeyWord(current);
				twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入 <=、   >=
				ch=GetChar();
				continue;
			}
			else
			{				
				InPoint.SetColumn(sym_word);///////////
				i=SearchKeyWord(current);
				twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());//插入 <、   >
				continue;
			}
		}
		
     	if(ch==47)
		{
			sym_word=sym_column;//////////
			current=ch;
			ch=GetChar();
			if(ch==47){
				do{
					ch=GetChar();
				}while(ch!=10);
				ch=GetChar();
				goto label1;
			}
			else if(ch==42){
				do{
					do{
						ch=GetChar();
					}while(ch!=42);
					ch=GetChar();
					if(ch==47)
					{
						ch=GetChar();
						goto label1;
					}
				}while(ch!=47);
			}

			InPoint.SetColumn(sym_word);///////////
			i=SearchKeyWord(current);
			twoelement.Insert(i,current,0,InPoint.GetRow(),InPoint.GetColumn());
            label1:
			continue;    
		}		  
		else 		
			ch=GetChar();//滤掉空格等
	
	}
		

}
//保存词法分析结果
void CPL0Doc::OnWordAnalyzeFile() 
{
	// TODO: Add your command handler code here

	CString text="",n;
	n+=(char)13;
	n+=(char)10;
	text=" 二元组:"+n+twoelement.OutputTwoElement()+n+ " 常量表: "+n;
	text+=defconstant.OutputDefConstant();
	text+=n+"   变量表:"+n;
	text+=defsymbol.OutputDefSymbol();
	int length=text.GetLength();
	
	CString PathName;
	CFileDialog dlg(false,"txt","词法分析结果",NULL,"文本文档|*.txt|所有文件(*.*)|*.*||");
	if(dlg.DoModal()==IDOK) PathName=dlg.GetPathName();///////////////////
	else return;

	CFile f;
	if(!f.Open(PathName,CFile::modeCreate|CFile::modeWrite)) return;
	char *temp=new char[length+1];
	for(int i=0;i<length;i++) temp[i]=text.GetAt(i);
	f.Write(temp,length);
	delete temp;
	f.Close();
}
//查看词法分析结果
void CPL0Doc::OnWordAnalyzeSee() 
{
	// TODO: Add your command handler code here
	CString a="",b,c,d,e,f;
	CString text,n;
	n+=(char)13;
	n+=(char)10;
	text="单词表:(种类,名字,数值,行号,列号)"+n+n+twoelement.OutputTwoElement()+n;
	text+="符号表:(名字,种类, 常量值,层次)"+n;
	for(int t=1;t<TX;t++)//t=0
		{
			b.Empty();
			c.Empty();
			d.Empty();
			e.Empty();
			f.Empty();
	
			b.Format("   %d    ",table[t].kind);
			c.Format("   %d    ",table[t].value);
			d.Format("   %d    ",table[t].level);
			f.Format("%d",t);
			a+=(f+":   "+table[t].name +"---" + b +"---"+ c +"---"+ d   +"  " +n);
		}	
	text+=a+n+ "常量表:(常量指针,数值) "+n;
	text+=defconstant.OutputDefConstant();
	text+=n+"变量表:"+n;
	text+=defsymbol.OutputDefSymbol();

	CView* cv;
	POSITION p=GetFirstViewPosition();
	cv=GetNextView(p);
	cv=GetNextView(p);
	cv=GetNextView(p);
	cv->SetWindowText(text);	
}




bool CPL0Doc::Generate(Functions func,int lev,int addr)
{
	
	Codes[CIndex].function = func;
	Codes[CIndex].levdiff = lev;
	Codes[CIndex].Addr = addr;
	CIndex ++;
	return true;
}
//处理声明
void CPL0Doc::Constdeclaration(int & dep)
{
	do
	{	  
	   TXCode++;
	   Advanced();
	   Advanced();
	   ////////////////
	   if(Sym==13||Sym==14)
		   Advanced();
	   ///////////////////
	   Advanced();
	}while(Sym==27);
}


void CPL0Doc::Vardeclaration(int & dep)
{
   do
   {   	
	   Advanced();	  
	   table[++TXCode].address=dep; 
	   dep++;//变量的个数加一
	   Advanced();
   }while(Sym == 27);//comma	
}

void CPL0Doc::Advanced(int i)
{
	if(i==0)
	{
		MyPointer=twoelement.head;
		MyAssitPointer=MyPointer;
	}
	else if(MyPointer!=NULL)
	{
		MyPointer=MyPointer->next;
	}
	if(MyPointer!=NULL)
	{
		Sym=MyPointer->sym;	
		if(Sym==888) temp=MyPointer->Name;
		else if(Sym==999) num=defconstant.OutputDefConstant(MyPointer->val);
	}
	else
		Sym=100;	
}
////找到标识符在符号表中的位置
int CPL0Doc::Position(CString idname)
{
	int p = -1;
	for(int i = 1;i <= TXCode;i++)//i=0
	{
		if(table[i].name == idname)
		{
			p = i;
			break;
		}
	}

	return p;
}

//因子分析
void CPL0Doc::Factor(int lev,int tx)
{	
	int i = -1;	
	//分支 identifier
	if(Sym == 888)
	{	
		i = Position(temp);	
		switch(table[i].kind)//生成代码
		{
		case 0:	Generate((Functions)1,0,table[i].value);break;//lit	
		case 1:	Generate((Functions)3,lev-table[i].level,table[i].address);break;//lod		
		}	
		Advanced();
	}

	//分支 number
	else if(Sym == 999)//number
	{				
		Generate((Functions)1,0,num);//lit		
		Advanced();
	}
	//分支 (--)
	else if(Sym == 24)//lparen

⌨️ 快捷键说明

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