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

📄 pascalcompiler.cpp

📁 袖珍型的pascal编译器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////

void CPascalCompiler::InstrCompusa()
{
	if (NextToken()!= TT_KW_BEGIN)
		throw error(SET_EXPECTED, CString("begin"));;
	while (1)
	{
		Instr();
		if (NextToken()==TT_KW_END)
		{
			PushBack();
			break;
		}
		PushBack();
		if (NextToken()==';')
			if (NextToken()==TT_KW_END)
			{
				PushBack();
				break;
			}
			else PushBack();
		else throw error(SET_EXPECTED, CString("end or ;"));
	}
	if (NextToken()!=TT_KW_END)
		throw error(SET_EXPECTED, CString("end"));
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:34:20 PM
// Function name	: CPascalCompiler::ExprStatica
// Description	    : 
// Return type		: void 
// Argument         : ExprInfo &ct
///////////////////////////////////////////////////////////////

void CPascalCompiler::ExprStatica(ExprInfo &ct)
{
	
	ExprInfo cres;
	REAL rResult = 0;	
	CHAR cResult = 0;
	INTEGER	nResult = 0;
	int type = 0;

	int c = '+';
	while (1)
	{
		TermenStatic(cres);

		switch (type)	// tipul termenului precedent
		{
		case ET_REAL:
			if (cres.m_nAtribTip  !=ET_REAL)
				throw error(SET_INVALID_OP_TYPES,CString("real type expected"));
			switch (c)
			{
			case '+':
				rResult += cres.m_dAttribValue ;
				break;
			case '-':
				rResult -= cres.m_dAttribValue ;
				break;
			}

		case ET_INTEGER:
			if (cres.m_nAtribTip  !=ET_INTEGER)
				throw error(SET_INVALID_OP_TYPES,CString("integer type expected"));
			switch (c)
			{
			case '+':
				nResult += cres.m_nAttribValue ;
				break;
			case '-':
				nResult -= cres.m_nAttribValue ;
				break;
			}
			break;
		case ET_CHAR:
			if (cres.m_nAtribTip  !=type)
				throw error(SET_INVALID_OP_TYPES,CString("Char type expected"));
			switch (c)
			{
			case '+':
				cResult += cres.m_cAttribValue;
				break;
			case '-':
				throw error(SET_INVALID_OP,CString("Can'tsubstract two strings"));
				break;
			}
			break;
		default:
			cResult = cres.m_cAttribValue ;
			rResult = cres.m_dAttribValue ;
			nResult = cres.m_nAttribValue ;
			type = cres.m_nAtribTip;
		}
		int val = NextToken();
		if (val!='+' && val != '-')
		{
			PushBack();
			break;
		}
		c = val;
	}
	ct.m_dAttribValue  = rResult;
	ct.m_cAttribValue  = cResult;
	ct.m_nAttribValue  = nResult;
	ct.m_nAtribTip  = type;
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:34:30 PM
// Function name	: CPascalCompiler::DeclVar
// Description	    : 
// Return type		: void 
// Argument         : int &varSize
///////////////////////////////////////////////////////////////

void CPascalCompiler::DeclVar(int &varSize)
{
	TypeInfo info;
	while (1)
	{
		if (NextToken() != TT_WORD)
			throw error(SET_EXPECTED, CString("identifier"));
		info.m_VarList .AddTail (GetStrValue());	// insert var name to the list
		if (NextToken()!=',')
		{
			PushBack();
			break;
		}
	}
	if (NextToken()!=':')
		throw error(SET_EXPECTED, CString(":"));
	Tip(info);
	// insert tyhe symbols in the symbol table
	POSITION pos = info.m_VarList .GetHeadPosition ();
	while (pos != NULL)
	{
		CString name = info.m_VarList .GetNext(pos);
		Symbol *simb =  new Symbol;
		simb->m_nNivel = m_nVNivel;
		simb->m_nClass = info.m_nClass ;
		simb->m_nType = info.m_nType ;
		simb->m_nIndMin = info.m_nIndMin ;
		simb->m_nIndMax = info.m_nIndMax ;
		simb->m_sName = name;
		simb->m_nAdrel = varSize ;
		varSize += info.m_nSize;
		InsertSymbol(simb);
	}
	// hey am I cool or what?
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:34:39 PM
// Function name	: CPascalCompiler::TipTablou
// Description	    : 
// Return type		: void 
// Argument         : TypeInfo& info
///////////////////////////////////////////////////////////////

void CPascalCompiler::TipTablou(TypeInfo& info)
{
	if (NextToken() != TT_KW_ARRAY)
		throw error(SET_EXPECTED, CString("array"));
	if (NextToken() != '[')
		throw error(SET_EXPECTED, CString("["));

	if (NextToken()	!= TT_INTEGER)	// trebuie modificat pentru numar zecimal
		throw error(SET_EXPECTED, CString("number"));
	info.m_nIndMin = (int) GetNumValue();
	if (NextToken() != TT_DOTDOT)
		throw error(SET_EXPECTED, CString(".."));
	
	if (NextToken() != TT_INTEGER)	// trebuie modificat pentru numar zecimal
		throw error(SET_EXPECTED, CString("number"));
	info.m_nIndMax = (int) GetNumValue();
	// verifica daca indicii sunt corecti (indmin<indmax)
	if (info.m_nIndMin>=info.m_nIndMax)
		throw error(SET_GENERAL,CString("The Ind MAX must be greater than Ind MIN"));
	if (NextToken() != ']')
		throw error(SET_EXPECTED, CString("]"));
	if (NextToken() != TT_KW_OF)
		throw error(SET_EXPECTED, CString("of"));
	TipSimplu(info);
	info.m_nSize *= info.m_nIndMax - info.m_nIndMin + 1;
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:34:48 PM
// Function name	: CPascalCompiler::TipRecord
// Description	    : 
// Return type		: void 
// Argument         : TypeInfo& info
///////////////////////////////////////////////////////////////

void CPascalCompiler::TipRecord(TypeInfo& info)
{
	info.m_nSize  = 0;
	if (NextToken() != TT_KW_RECORD)
		throw error(SET_EXPECTED, CString("record"));;
	while (1)
	{
		DeclCamp(info);
		int val = NextToken();
		if (val != ';')
		{
			PushBack();
			break;
		}
	}
	if (NextToken() != TT_KW_END)
		throw error(SET_EXPECTED, CString("end"));
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:34:56 PM
// Function name	: CPascalCompiler::DeclCamp
// Description	    : 
// Return type		: void 
// Argument         : TypeInfo&info
///////////////////////////////////////////////////////////////

void CPascalCompiler::DeclCamp(TypeInfo&info)
{
	StringList list;
	while (1)
	{
		if (NextToken()!= TT_WORD)
			throw error(SET_EXPECTED, CString("identifier"));
		list.AddTail(GetStrValue());
		if (NextToken()!= ',')
		{
			PushBack();
			break;
		}
	}
	if (NextToken()!=':')
		throw error(SET_EXPECTED, CString(":"));
	TypeInfo secinfo;
	TipSimplu(secinfo);
	// si acum sa introducem un simbol pentru bullshit-ul de camp de record
	POSITION pos = list.GetHeadPosition ();
	while (pos!=NULL)
	{
		CString name = list.GetNext(pos);
		Symbol *simb = new Symbol;
		simb->m_sName = name;
		simb->m_nClass = CT_VAR_RECORD_FIELD;
		simb->m_nType  = secinfo.m_nType ;
		simb->m_nDeplRec = info.m_nSize ;
		info.m_nSize  += secinfo.m_nSize ;
		simb->m_ListaRec .RemoveAll();
		simb->m_ListaRec .AddTail(&info.m_VarList);	// legaturile spre variabilele care sunt de tipul record
		InsertSymbol(simb);
	}
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:35:07 PM
// Function name	: CPascalCompiler::TermenStatic
// Description	    : 
// Return type		: void 
// Argument         : ExprInfo &ct
///////////////////////////////////////////////////////////////

void CPascalCompiler::TermenStatic(ExprInfo &ct)
{
	REAL dResult = 1;
	CHAR cResult = 0;
	INTEGER nResult = 1;
	int type = 0;
	ExprInfo cres;
	int c;
	
	while (1)
	{
		FactorStatic(cres);

		switch (type)	// tipul termenului precedent
		{
		case ET_REAL:
			if (cres.m_nAtribTip  !=ET_REAL)
				throw error(SET_INVALID_OP_TYPES,CString("real type expected"));
			switch (c)
			{
			case '*':
				dResult *= cres.m_dAttribValue ;
				break;
			case '/':
				dResult /= cres.m_dAttribValue ;
				break;
			default:
				throw error(SET_INVALID_OP,CString(""));
			}

		case ET_INTEGER:
			if (cres.m_nAtribTip  !=ET_INTEGER)
				throw error(SET_INVALID_OP_TYPES,CString("integer type expected"));
			switch (c)
			{
			case '*':
				nResult *= cres.m_nAttribValue ;
				break;			
			case TT_KW_DIV:
				nResult /= cres.m_nAttribValue ;
				break;
			case TT_KW_MOD:
				nResult %= cres.m_nAttribValue ;
				break;
			default:
				throw error(SET_INVALID_OP,CString("you can't divide two integers"));
			}
			break;
		case ET_CHAR:
			throw error(SET_INVALID_OP,CString("You can't do that with char's"));
			break;
		default:
			cResult = cres.m_cAttribValue ;
			dResult = cres.m_dAttribValue ;
			nResult = cres.m_nAttribValue ;
			type = cres.m_nAtribTip ;
		}

		int val = NextToken();
		if (val!='*' && val != '/' && val!=TT_KW_MOD && val != TT_KW_DIV)
		{
			PushBack();
			break;
		}
		c = val;
	}
	ct.m_dAttribValue  = dResult;
	ct.m_cAttribValue  = cResult;
	ct.m_nAttribValue  = nResult;
	ct.m_nAtribTip  = type;
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:35:18 PM
// Function name	: CPascalCompiler::FactorStatic
// Description	    : 
// Return type		: void 
// Argument         : ExprInfo &ct
///////////////////////////////////////////////////////////////

void CPascalCompiler::FactorStatic(ExprInfo &ct)
{
	int val = NextToken();
	if (val == TT_WORD)
	{
		// search for another constant
		Symbol *simb = NULL;
		if (!RetreaveSymbol(GetStrValue(),simb))
			throw error(SET_GENERAL,CString("Constant expected"));
		if (simb->m_nClass!=CT_CONST)
			throw error(SET_GENERAL,CString("Constant expected"));
		ct.m_nAtribTip = simb->m_nType;
		switch (simb->m_nType)
		{
		case ET_INTEGER:
			ct.m_nAttribValue = CV_INTEGER(simb->m_Val) ;
			break;
		case ET_REAL:
			ct.m_dAttribValue = CV_REAL(simb->m_Val) ;
			break;
		case ET_CHAR:
			ct.m_cAttribValue = CV_CHAR(simb->m_Val) ;
			break;
		}

		return;	// this can be only a constant
	}
	if (val == TT_INTEGER)
	{
		ct.m_nAttribValue  = (INTEGER) GetNumValue ();
		ct.m_nAtribTip  = ET_INTEGER;
		return;
	}
	if (val == TT_REAL)
	{
		ct.m_dAttribValue  = (REAL) GetNumValue ();
		ct.m_nAtribTip  = ET_REAL;
		return;
	}
	if (val == TT_CHAR)
	{
		ct.m_cAttribValue  = GetStrValue ()[0];
		ct.m_nAtribTip  = ET_CHAR;
		return;
	}
	if (val == '(')
	{
		ExprStatica(ct);
		if (NextToken()!=')')
			throw error(SET_EXPECTED, CString(")"));
		return;
	}
	throw error(SET_EXPECTED, CString("Identifier or number or constant"));
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:35:28 PM
// Function name	: CPascalCompiler::Instr
// Description	    : 
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::Instr()
{
	int val = NextToken();
	switch (val)
	{
	case TT_KW_WHILE:
		{
			PushBack();
			InstrWhile();
			break;
		}
	case TT_KW_REPEAT:
		{
			PushBack();
			InstrRepeat();
			break;
		}
	case TT_KW_FOR:
		{
			PushBack();
			InstrFor();
			break;
		}
	case TT_KW_CASE:
		{
			PushBack();
			InstrCase();
			break;
		}
	case TT_KW_BEGIN:
		{
			PushBack();
			InstrCompusa();
			break;
		}
	case TT_KW_PRINT:
		{
			PushBack();
			InstrPrint();
			break;
		}
	case TT_KW_READ:
		{
			PushBack();
			InstrRead();
			break;
		}
	case TT_KW_IF:
		{
			PushBack();
			InstrIf();
			break;
		}
	case TT_WORD:
			if (IsProc(GetStrValue()))
			{
				PushBack();
				ApelProcedura();
			}
			else
			{
				PushBack();
				Atribuire();
			}
			break;
	default:		 
			throw error(SET_EXPECTED, CString("Instruction"));
	}
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:35:38 PM

⌨️ 快捷键说明

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