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

📄 compiler.cpp

📁 这个也是我们的毕业设计课题
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Compiler.cpp: implementation of the CCompiler class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DFYSimulator.h"
#include "Compiler.h"
#include "MainFrm.h"
#include "OutputWindow.h"
#include"fstream"
using namespace std;
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCompiler::CCompiler()
{
	m_uErrorNum=0;
	m_uCodeSegSize=0;
	m_uDataSegSize=0;
	m_wDFYexeFileSize=0;
	m_wPdfRecordNum=0;
	m_uCodeLineNum=0;
	_instructions[0]="LD";
	_instructions[1]="ST";
	_instructions[2]="LEA";
	_instructions[3]="ADD";
	_instructions[4]="SUB";
	_instructions[5]="SLA";
	_instructions[6]="SRA";
	_instructions[7]="AND";
	_instructions[8]="OR";
	_instructions[9]="EOR";
	_instructions[10]="NOT";
	_instructions[11]="SLL";
	_instructions[12]="SRL";
	_instructions[13]="CPA";
	_instructions[14]="CPL";
	_instructions[15]="JMP";
	_instructions[16]="JPZ";
	_instructions[17]="JMI";
	_instructions[18]="JNZ";
	_instructions[19]="JZE";
	_instructions[20]="PUSH";
	_instructions[21]="POP";
	_instructions[22]="CALL";
	_instructions[23]="RET";
	_instructions[24]="INPORT";
	_instructions[25]="OUTPORT";
	_instructions[26]="EXIT";
	_instructions[27]="INTR";
	_instructions[28]="IRET";
	_instructions[29]="STI";
	_instructions[30]="CLI";
	_registers[0]="GR0";
	_registers[1]="GR1";
	_registers[2]="GR2";
	_registers[3]="GR3";
	_registers[4]="GR4";
	_flagsMap=NULL;
	_varInfo=NULL;
}

CCompiler::~CCompiler()
{
	FlagsMap* p=_flagsMap;
	FlagsMap* q=NULL;
	if(p!=NULL)
	{
		q=p->next;
		delete p;
		p=q;
	}

	VariableInfo* pp=_varInfo;
	VariableInfo* qq=NULL;
	if(pp!=NULL)
	{
		qq=pp->next;
		delete pp;
		pp=qq;
	}
}

BOOL CCompiler::Compile(char* asmSource,char* pdfFile,char* DFYexeFile)
{
	CMainFrame* pMainFrame=(CMainFrame*)AfxGetMainWnd();
	COutputWindow* pOutputWindow=pMainFrame->GetOutputWindow();
	pOutputWindow->ResetContent();
	ReportState("Assembling...");
	if(FirstScan(asmSource,pdfFile))
	{
		return SecondScan(asmSource,DFYexeFile);
	}
	else
		return FALSE;
}

void CCompiler::ReportState(CString strState)
{
	CMainFrame* pMainFrame=(CMainFrame*)AfxGetMainWnd();
	COutputWindow* pOutputWindow=pMainFrame->GetOutputWindow();
	if(pOutputWindow)
		pOutputWindow->ShowState(strState);

}

BOOL CCompiler::IsLegal(char* str)
{
	if(!str)return FALSE;
	int n=strlen(str);
	if(n==0)return FALSE;
	for(int i=0;i<n;i++)
	{
		if(str[i]=='_')
			continue;
		if(str[i]>='0'&&str[i]<='9')
			continue;
		if(str[i]>='a'&&str[i]<='z')
			continue;
		if(str[i]>='A'&&str[i]<='Z')
			continue;
		return FALSE;
	}
	return TRUE;
}

BOOL CCompiler::IsNumber(char* strWord)
{
	if(!strWord)return FALSE;
	int n=strlen(strWord);
	if(n==0)return FALSE;
	for(int i=0;i<n;i++)
	{
		if(strWord[i]>='0'&&strWord[i]<='9')
		continue;
		return FALSE;
	}
	return TRUE;
}
BOOL CCompiler::IsInstruction(char *strWord)
{
	if(!strWord)return FALSE;
	int n=strlen(strWord);
	if(n==0)return FALSE;
	
	for(int i=0;i<35;i++)
	{
		if(strcmp(strWord,_instructions[i])==0)
			return i+1;//return the instruction code
	}
	return FALSE;
}

BOOL CCompiler::IsRegister(char *strWord)
{
	if(!strWord)return FALSE;
	int n=strlen(strWord);
	if(n==0)return FALSE;
	for(int i=0;i<5;i++)
	{
		if(strcmp(strWord,_registers[i])==0)
			return i+1;//reture the number of the register ,but not 
						//register code
	}
	return FALSE;
}

BOOL CCompiler::FirstScan(char *asmSourceName, char *pdfFileName)
{
	BOOL bStart=FALSE;
	BOOL bData=	FALSE;
	char* word=new char[20];
	char* word2=new char[20];
	UNSHORT uAddr=0;//keep the current instruction address
	UNSHORT uLine=0;//the line number
	m_wPdfRecordNum=0;
	CString str;
	ifstream asmFile;
	char* pBuf=new char[200];
	ReportState("first scaning...");
	str.Format("scanling file:%s...",asmSourceName);
	ReportState(str);
	asmFile.open(asmSourceName);
	if(!asmFile)
	{
		str.Format("fatal error:can't open the file %s or the file is not exist",asmSourceName);
		m_uErrorNum+=1;
		ReportState(str);
		delete[] word;
		delete[]word2;
		delete[] pBuf;
		return FALSE;
	}//end:!admFile
	while(!asmFile.eof())
	{
		uLine+=1;//line number +1
		str.Format("anylize line:%d...",uLine);
		ReportState(str);
		asmFile.getline(pBuf,200);
		word=GetWordFromLine(0,pBuf);
		if(IsEmpty(word))continue;//if the line is empty
		if(IsComment(word))continue;//if the line is comment
		if(!IsLegal(word))//if the word is not legal
		{
			str.Format("fatal error:Line %d \'%s\'is illegal",uLine,word);
			m_uErrorNum+=1;
			ReportState(str);
			continue;
		}//end:the word is not legal
		else//is the word is a legal identifier
		{
			if(!bStart)//if haven't find the 'START'
			{
				if(strcmp(word,"START")==0)
				{
					bStart=TRUE;
					continue;
				}
				else
				{
					m_uErrorNum+=1;
					ReportState("fatal error:cant't find 'START' ");
					delete[] word;
					delete[]word2;
					delete[] pBuf;
					return FALSE;
				}
			}
			else//have been find the 'START'
			{
				if(strcmp(word,"END")==0)//if go to the end
				{
					uAddr-=1;
					break;
				}
				else if(strcmp(word,"DATA")==0)
				{
					bData=TRUE;
					continue;
				}
				if(!bData)//haven't find the 'DATA'
				{
					if(!IsInstruction(word))//is flag
					{
						AddFlag(word,uAddr);
					}
					uAddr+=2;
					m_wDFYexeFileSize+=2;
					m_uCodeSegSize+=2;
				
				}
				else//have find the 'DATA',,into the data segment
				{
					word2=GetWordFromLine(1,pBuf);
					if(strcmp(word2,"DC")==0)
					{
						word2=GetWordFromLine(2,pBuf);
						if(IsNumber(word2))
						{
							AddVariable(word,uAddr,atoi(word2));
							uAddr+=1;
							m_uDataSegSize+=1;
							m_wDFYexeFileSize+=1;
							m_wPdfRecordNum+=1;
						}
						else
						{
							str.Format("fatal error: Line %d,the variable value haven't initialized",uLine);
							m_uErrorNum+=1;
							ReportState(str);
							continue;
						}//end:IsNumber
					}//end:strcmp
					else
					{
						str.Format("fatal error: Line %d,the second word should be \'DC\'",uLine);
						m_uErrorNum+=1;
						ReportState(str);
						continue;
					}

				}//end:have find the data
				continue;
			}//end:have find the 'START'
		}//legal
	}//while
	m_uCodeLineNum=uLine;
	asmFile.close();
	if(!bStart)
	{
		ReportState("fatal error: can't find \'START\'");
		return FALSE;
	}
	str.Format("generate file: %s",pdfFileName);
	ReportState(str);
	ofstream pdffile;
	pdffile.open(pdfFileName);
	if(!pdffile)
	{
		str.Format("fatal error:can't create the file %s or the file is not exist",pdfFileName);
		m_uErrorNum+=1;
		ReportState(str);
	}
	PdfFileHeader head;
	head.wFileVersion=1;
	head.wRecordNumber=m_wPdfRecordNum;
	pdffile<<head.wFileVersion<<' '<<head.wRecordNumber<<' ';
	VariableInfo *p=_varInfo;
	while(p!=NULL)
	{
		pdffile<<' '<<p->strVarName<<' '<<p->uVarAddr<<' '<<p->wValue<<' ';
		p=p->next;
	}
	pdffile.close();
	delete[] word;
	delete[]word2;
	delete[] pBuf;
	if(m_uErrorNum==0)
	{
		ReportState("first scan succeed");
		return TRUE;
	}
	else
	{
		ReportState("first scan failed");
		str.Format("%d errors",m_uErrorNum);
		ReportState(str);
		return FALSE;
	}
}
char* CCompiler::GetWordFromLine(int nIndex, char *strSrc)
{
	char c;
	char* str;//used to reserve the return value
	int wordSize=0;
	int index=0;
	int pos=0;//record the current char pos
	int lineSize=strlen(strSrc);
	if(lineSize==0)	return NULL;
	//filter the backspace first
	c=strSrc[pos];
	while(c==' ')
	{
		pos++;
		if(pos)break;
		c=strSrc[pos];
	}
	if(pos>=lineSize)return NULL;
	//filter the other word and backspace
	if(nIndex<0)nIndex=0;
	while(index<nIndex)
	{
		while(c!=' ')//filter the next word
		{
			pos++;
			if(pos>=lineSize)break;
			c=strSrc[pos];
		}
		while(c==' ')//filter the next backspace
		{
			pos++;
			if(pos>=lineSize)break;
			c=strSrc[pos];
		}
		index+=1;
	}
	if(pos>=lineSize)return NULL;
	//into the word 
	while(c!=' ')
	{
		wordSize++;
		if(pos+wordSize>=lineSize)break;
		c=strSrc[pos+wordSize];
	}
	str=new char[wordSize+1];
	for(int i=0;i<wordSize;i++)
		str[i]=strSrc[pos+i];
	str[wordSize]='\0';
	return str;

}

BOOL CCompiler::FindFlag(char *flag, UNSHORT &uAddr)//the flag should not be NULL
{
	if(!flag)return FALSE;
	if(strlen(flag)==0)return FALSE;
	FlagsMap* p=_flagsMap;
	if(!p)return FALSE;
	while(p!=NULL)
	{
		if(strcmp(p->strFlagName,flag)==0)
		{
			uAddr=p->uFlagAddr;
			return TRUE;
		}
		p=p->next;
	}
	return FALSE;
}

BOOL CCompiler::FindVariable(char *var, UNSHORT &uAddr,WORD& wVar)//the flag should not be NULL
{
	if(!var)return FALSE;
	if(strlen(var)==0)return FALSE;
	VariableInfo* p=_varInfo;
	if(!p)return FALSE;
	while(p!=NULL)
	{
		if(strcmp(p->strVarName,var)==0)
		{
			uAddr=p->uVarAddr;
			wVar=p->wValue;
			return TRUE;
		}
		p=p->next;
	}
	return FALSE;
}

BOOL CCompiler::IsEmpty(char *strWord)
{
	if(!strWord)return TRUE;
	if(strlen(strWord)==0)
		return TRUE;
	return FALSE;
}

BOOL CCompiler::IsComment(char *strWord)
{
	if(!strWord)return FALSE;
	if(strlen(strWord)==0)
		return FALSE;
	
	if(strWord[0]==';')
		return TRUE;
	return FALSE;

}
void CCompiler::AddFlag(char *flag, UNSHORT uAddr)
{
	FlagsMap* p=_flagsMap;
	FlagsMap* newNode=NULL;
	FlagsMap* q=NULL;
	if(p==NULL)
	{

⌨️ 快捷键说明

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