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

📄 pl0doc.cpp

📁 编译原理实践教程PL0语言编译程序源代码。参考书:清华大学出版社的《编译原理》作者吕映芝、张素琴等。 实现主要功能有:对使用PL0语言编写的程序进行词法分析
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// PL0Doc.cpp : implementation of the CPL0Doc class
//

#include "stdafx.h"
#include "PL0.h"
#include  "Show.h"
#include "AnotherShow.h"
#include "PL0Doc.h"
#include "Instruction.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPL0Doc

IMPLEMENT_DYNCREATE(CPL0Doc, CDocument)

BEGIN_MESSAGE_MAP(CPL0Doc, CDocument)
	//{{AFX_MSG_MAP(CPL0Doc)
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
	ON_COMMAND(ID_SYNTAX_ANALYZE, OnSyntaxAnalyze)
	ON_COMMAND(ID_WORD_ANALYZE, OnWordAnalyze)
	ON_COMMAND(ID_WORD_ANALYZE_FILE, OnWordAnalyzeFile)
	ON_COMMAND(ID_WORD_ANALYZE_SEE, OnWordAnalyzeSee)
	ON_COMMAND(ID_CODES_ANALYZE, OnCodesAnalyze)
	ON_COMMAND(ID_EXECUTE, OnExecute)
	ON_COMMAND(ID_CODESVIEW, OnCodesview)
	ON_COMMAND(IDM_Instru, OnInstru)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPL0Doc construction/destruction

CPL0Doc::CPL0Doc()
{

	// TODO: add one-time construction code here
	for(int i=0;i<=KeywordTotal;i++) keyword[i].Empty();
	keyword[1]+="begin";
	keyword[2]+="end";
	keyword[3]+="if";
	keyword[4]+="then";
	keyword[5]+="var";
	keyword[6]+="const";
	keyword[7]+="procedure";
	keyword[8]+="call";
	keyword[9]+="write";
	keyword[10]+="read";
	keyword[11]+="while";
	keyword[12]+="do";
	keyword[13]+="+";
	keyword[14]+="-";
	keyword[15]+="*";
	keyword[16]+="/";
	keyword[17]+=":=";
	keyword[18]+="<";
	keyword[19]+="<=";
	keyword[20]+="=";
	keyword[21]+=">";
	keyword[22]+=">=";
	keyword[23]+=".";
	keyword[24]+="(";
	keyword[25]+=")";
	keyword[26]+=";";
	keyword[27]+=",";
	keyword[28]+="#";
	keyword[29]+="odd";

	//TX=0;
	sym_line = 1;
	TX=1;
	err[1]="常数说明中的' = '写成' := '。";
	err[2]="常数说明中的' = '后应该是数字。";
	err[3]="常数说明中的标识符后应该是' = '。";
	err[4]="const,var,procedure后应该为标识符。";
	err[5]="漏掉了' , '或' ; '。";
	err[6]="过程说明后的符号不正确(应该是语句开始符,或过程定义符)。";
	err[7]="' ; '后应该是过程说明。";
	err[8]="程序体内语句部分的后跟符不正确。";
	err[9]="程序结尾丢了'.'。";
	err[10]="语句之间漏了';'。";
	err[11]="标识符未说明。";
	err[12]="赋值语句中,赋值号左部标识符属性应该是变量。";
	err[13]="赋值语句左部标识符后应该是赋值号':='。";
	err[14]="call后应该为标识符。";
	err[15]="call后标识符应该为过程名。";
	err[16]="条件语句中丢了'then'。";
	err[17]="前面丢了'end'或';'。";
	err[18]="while型循环语句中丢了'do'。";
	err[19]="语句后的符合不正确。";
	err[20]="应该为关系运算符。";
	err[21]="表达式内标识符属性不能是过程。";
	err[22]="表达式中漏掉')'。";
	err[23]="因子后的非法符合。";
	err[24]="表达式的开始符不能式此符合。";
	err[25]="标识符定义重复";
	err[26]="过程说明中,标识符后漏掉了';'。";
	err[27]="' , '后应该是标识符。";
	err[31]="数越界。";
	err[32]="read语句括号中的标识符不是变量。";
	err[33]="未定义的运算类型!";
}

CPL0Doc::~CPL0Doc()
{
}

BOOL CPL0Doc::OnNewDocument()
{
	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	TX=1;
	CIndex=0;
	defconstant.Empty();  //置空常量表
	defsymbol.Empty();    //置空变量表
	twoelement.Empty();   //置空二元组表


	CView* cv;
	POSITION p=GetFirstViewPosition();
	cv=GetNextView(p);
	cv=GetNextView(p);
	cv->SetWindowText("");
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CPL0Doc serialization

void CPL0Doc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CPL0Doc diagnostics

#ifdef _DEBUG
void CPL0Doc::AssertValid() const
{
	CDocument::AssertValid();
}

void CPL0Doc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPL0Doc commands

BOOL CPL0Doc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
	// TODO: Add your specialized creation code here

	CString text;
	CFile f;
	if(!f.Open(lpszPathName,CFile::modeRead)) return false;//按输入文件名与其路径,打开文件
	int length=f.GetLength();
	char *temp=new char[length+1];
	f.Read(temp,length);
	for(int i=0;i<length;i++) text+=temp[i];//文件内容全部加载到text中去
	delete temp;
	f.Close();

	CView* cv;
	POSITION p=GetFirstViewPosition();
	cv=GetNextView(p);
	cv=GetNextView(p);
	cv->SetWindowText(text);//将文件内容添加到view 中去

	TX=1;
	CIndex=0;
	defconstant.Empty();  //置空常量表
	defsymbol.Empty();    //置空变量表
	twoelement.Empty();   //置空二元组表
	return TRUE;
}

BOOL CPL0Doc::CanCloseFrame(CFrameWnd* pFrame) 
{
	// TODO: Add your specialized code here and/or call the base class

	return CDocument::CanCloseFrame(pFrame);
}

BOOL CPL0Doc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	// TODO: Add your specialized code here and/or call the base class
	CView* cv;
	POSITION p=GetFirstViewPosition();
	cv=GetNextView(p);
	cv=GetNextView(p);
	CString text;
	cv->GetWindowText(text);//得到view中的数据

	CString pn;
	pn=lpszPathName;
	if(pn.Find(".txt")<0) pn+=".txt";

	CFile f;
	if(!f.Open(pn,CFile::modeCreate|CFile::modeReadWrite)) return false;
	int length=text.GetLength();
	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();
	return true;
	//return CDocument::OnSaveDocument(lpszPathName);
}

void CPL0Doc::DeleteContents() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CDocument::DeleteContents();
}

void CPL0Doc::OnFileSaveAs() 
{
	// TODO: Add your command handler code here
	CString PathName;
	CFileDialog dlg(false,"txt","PL0源文件",NULL,"文本文档|*.txt|所有文件(*.*)|*.*||");
	if(dlg.DoModal()==IDOK) PathName=dlg.GetPathName();
	else return;

	CView* cv;
	POSITION p=GetFirstViewPosition();
	cv=GetNextView(p);
	cv=GetNextView(p);
	CString text;
	cv->GetWindowText(text);

	CFile f;
	if(!f.Open(PathName,CFile::modeCreate|CFile::modeWrite)) return;
	int length=text.GetLength();
	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();
}
//搜索关键字
int CPL0Doc::SearchKeyWord(CString str)//是否是关键字,是哪种关键字
{
	for(int i=KeywordTotal;i>0;i--)
		if(!keyword[i].Compare(str)) break;
	return i;
}
//打印关键字
CString CPL0Doc::OutputKeyWord()
{
	CString str,temp;
	for(int i=1;i<=KeywordTotal;i++){
		temp.Empty();
		temp.Format("%d",i);
		str+=(temp+","+keyword[i]+"\n");
	}
	return str;
}
//词法分析取字母
char CPL0Doc::GetChar(int n)                                                                           
{
	if(n){
		char ch;
		if(nPreChar<source.GetLength())
		{
			ch=source.GetAt(nPreChar);
			nPreChar++;
			if(ch==10) 
			{
				nPreLine++;
				sym_column=0;
			}
			else
			{
				sym_column++;
				
				InPoint.SetRow(nPreLine);
			}
			
			
		//	InPoint.SetColumn(sym_column);

			return ch;
		}
		else return (char)127;
	}
	else{
		CView* cv;
		POSITION p=GetFirstViewPosition();
		cv=GetNextView(p);
		cv=GetNextView(p);
		cv->GetWindowText(source);	
		nPreChar=0;
		nPreLine=1;//行标的初始化
		sym_column=0;
		sym_word=sym_column;
		return (char)0;
	}
}
//程序
void CPL0Doc::program()
{
	block(0,0);
	if(sym==23)
		Advance();//'.'
	else error(9);//丢掉了结尾符
}
//子程序
void CPL0Doc::block(int lev, int tx)
{
	if(sym==6){//const
		do{
			Advance();//向前读入一个单词
			if(sym==888){
				CString temp=sym_name;
				if(test(temp,lev,tx)) error(25);//标识符说明重复
				Advance();
				if(sym==20){//'='
					Advance();
					if(sym==999){//数字
						enter(temp,CON,lev,sym_val,0,0);//,PreTEI->line,PreTEI->column
						Advance();
					}

					else if(sym==13)
					{
						Advance();
						if(sym==999)
						{
							enter(temp,CON,lev,sym_val,0,0);//,PreTEI->line,PreTEI->column
						    Advance();
						}
						else error(2);
					}
					else if(sym==14)
					{
						Advance();
						if(sym==999)
						{
							enter(temp,CON,lev,-sym_val,0,0);//,PreTEI->line,PreTEI->column
						    Advance();
						}
						else
							error(2);
					}
					else error(2);//'='后应该是数字
				}
				else if(sym==17) error(1);//'='写成了':='
				else error(3);//标识符后应该是'='
			}
			else error(4);//const、var、procedure后应该为标识符
		}while(sym==27);//','
		if(sym==26) Advance();//';'
		else error(5);//漏掉了','或';'
	}
	if(sym==5){//var
		do{
			Advance();
			if(sym==888){
				if(test(sym_name,lev,tx)) error(25);//标识符说明重复
				enter(sym_name,VAR,lev,0,0,0);//,PreTEI->line,PreTEI->column
				Advance();
			}
			else error(4);//const、var、procedure后应该为标识符
		}while(sym==27);//','
		if(sym==26) Advance();//';'
		else error(5);//漏掉了','或';'
	}
	while(sym==7){//'procedure'
		Advance();
		if(sym==888){
			if(test(sym_name,lev,tx)) error(25);//标识符说明重复
			enter(sym_name,PRO,lev,0,0,0);//,PreTEI->line,PreTEI->column
			Advance();
			if(sym==26){//';'
				Advance();
				block(lev+1,TX);
				if(sym==26) Advance();//';'
				else error(6);//过程说明中,标识符后漏掉了';'
			}
			else error(26);//过程说明中,标识符后漏掉了';'
		}
		else error(4);//const、var、procedure后应该为标识符
	}
    statement(lev,tx);
}
//句子
void CPL0Doc::statement(int lev, int tx)
{
	if(sym==888){//赋值语句
		if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,PRO)) error(12);//赋值语句中,左部标识符应是变量
		else if(!test(sym_name,lev,tx,VAR)) error(11);//变量未定义
		Advance();
		if(sym==17){// :=
			Advance();
			expression(lev,tx);
		}
		else error(13);//赋值语句中,标识符后应是赋值符合 :=
	}
	else if(sym==8){//call
		Advance();
		if(sym==888){
			if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,VAR)) error(15);//call后应该为过程名
			else if(!test(sym_name,lev,tx,PRO)) error(15);//call后应该为过程名
			Advance();
		}
		else error(14);//call后应该为标识符
	}
	else if(sym==1){//begin
		Advance();
		statement(lev,tx);
		while(sym==26){//";"
			Advance();
			statement(lev,tx);
		}
		if(sym==2) Advance();//end
		else error(17);//丢"end"或";"
	}
	else if(sym==3){//"if"
		Advance();
		condition(lev,tx);
		if(sym==4){//"then"
			Advance();
			statement(lev,tx);
		}
		else error(16);//丢了"then"
	}
	else if(sym==11){//"while"
		Advance();
		condition(lev,tx);
		if(sym==12){//"do"
			Advance();
			statement(lev,tx);
		}
		else error(18);//丢了"do"
	}
	else if(sym==10){//"read"
		Advance();
		if(sym==24){// "("
			Advance();
			if(sym==888){//标识符
				if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,PRO)) error(32);//read语句括号中标识符不是变量
				else if(!test(sym_name,lev,tx,VAR)) error(11);//变量未定义
				Advance();
				while(sym==27){//","
					Advance();
					if(sym==888){
						if(test(sym_name,lev,tx,CON) || test(sym_name,lev,tx,PRO)) error(32);//read语句括号中标识符不是变量
						else if(!test(sym_name,lev,tx,VAR)) error(11);//变量未定义
						Advance();
					}
					else error(27);//' , '后应该是标识符。
				}
				if(sym==25) Advance();//")"
				else error(22);//漏掉")"
			}
			else error(32);//read语句括号中标识符不是变量
		}
		else error(24);//表达式开始符应该是"("
	}
	else if(sym==9){//write
		Advance();
		if(sym==24){//"("
			do{
				Advance();
				expression(lev,tx);
			}while(sym==27);//','
			if(sym==25) Advance();//")"
			else error(22);//漏掉")"
		}
		else error(24);//表达式开始符应该是"("
	}

}
//条件
void CPL0Doc::condition(int lev, int tx)
{

⌨️ 快捷键说明

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