www.pudn.com > 编译原理上机实验.rar > Compiler.cpp


// Compiler.cpp: implementation of the CCompiler class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "PL0.h" 
#include "Compiler.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CCompiler::CCompiler() 
{ 
	m_ntCifaLen=0; 
	m_aSourse[0]=0; 
	m_Interface.SourseBuffer=m_aSourse; 
	m_Interface.SemanticQuad=quad; 
	m_Interface.LexicalDuad=m_tCifa; 
	m_Interface.QuadOpcodeTable=m_QuadOpCodeTable; 
	m_Interface.ErrorMessageTable=m_tErrorMessage; 
	m_Interface.ErrorNumber=0; 
	m_Interface.ErrorAddress=0; 
} 
 
CCompiler::~CCompiler() 
{ 
 
} 
 
char CCompiler::GetCurCh()//get ch and point does not ++ 
{ 
	return m_aSourse[m_pCurCh]; 
} 
 
void CCompiler::NextCh()//point ++ 
{ 
	m_pCurCh++; 
} 
 
char CCompiler::GetCh()//get ch and point ++ 
{ 
	return m_aSourse[m_pCurCh++]; 
} 
 
char CCompiler::GetNextCh()//get next ch and point does not ++ 
{ 
	if (m_aSourse[m_pCurCh]==0) return 0; 
	return m_aSourse[m_pCurCh+1]; 
} 
 
void CCompiler::CiFaFengXi() 
{ 
	BOOL flag=FALSE; 
	char token[MAX_LEX_LEN]; 
	int k,v; 
	Initial(); 
	for (int i=0;ivalue=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh-k; 
				m_ntCifaLen++; 
			} 
			else 
			{ 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=FindInCifaTab(token); 
				m_tCifa[m_ntCifaLen]->type=1; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh-k; 
				m_ntCifaLen++; 
			} 
		} 
		else if (isdigit(GetCurCh()))//digit 
		{ 
			k=0; 
			BOOL error=FALSE; 
			while (1) 
			{ 
				if (k<=MAX_NUMBER_LEN) token[k++]=GetCh(); 
				else 
				{ 
					error=TRUE; 
					NextCh(); 
				} 
				if (!isdigit(GetCurCh())) break; 
			} 
			token[k]=0; 
			v=::strtol(token,NULL,10); 
			if (error) 
			{ 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=1; 
				m_tCifa[m_ntCifaLen]->type=0; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh-k; 
				m_ntCifaLen++; 
			} 
			else 
			{ 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=v; 
				m_tCifa[m_ntCifaLen]->type=2; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh-k; 
				m_ntCifaLen++; 
			} 
		} 
		else 
		switch (GetCurCh())//other 
		{ 
		case '+': 
		case '-': 
		case '*': 
		case '~': 
		case '&': 
		case '|': 
		case '=': 
		case ';': 
		case '.': 
		case ',': 
		case '(': 
		case ')': 
			token[0]=GetCurCh(); 
			token[1]=0; 
			v=FindInKeyWordTab(token); 
			m_tCifa[m_ntCifaLen]=new CifaResult; 
			m_tCifa[m_ntCifaLen]->value=0; 
			m_tCifa[m_ntCifaLen]->type=v; 
			::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
			m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
			m_ntCifaLen++; 
			NextCh(); 
			break; 
		case '\0': 
			break; 
		case '/': 
			switch (GetNextCh()) 
			{ 
			case '*': 
				NextCh(); 
				NextCh(); 
				flag=TRUE; 
				break; 
			default: 
				token[0]=GetCurCh(); 
				token[1]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
			} 
			break; 
		case '<': 
			switch (GetNextCh()) 
			{ 
			case '=': 
				token[0]=GetCurCh(); 
				token[1]=GetNextCh(); 
				token[2]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
				NextCh(); 
				break; 
			case '>': 
				token[0]=GetCurCh(); 
				token[1]=GetNextCh(); 
				token[2]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
				NextCh(); 
				break; 
			default: 
				token[0]=GetCurCh(); 
				token[1]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
			} 
			break; 
		case '>': 
			switch (GetNextCh()) 
			{ 
			case '=': 
				token[0]=GetCurCh(); 
				token[1]=GetNextCh(); 
				token[2]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
				NextCh(); 
				break; 
			default: 
				token[0]=GetCurCh(); 
				token[1]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
			} 
			break; 
		case ':': 
			switch (GetNextCh()) 
			{ 
			case '=': 
				token[0]=GetCurCh(); 
				token[1]=GetNextCh(); 
				token[2]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
				NextCh(); 
				break; 
			default: 
				token[0]=GetCurCh(); 
				token[1]=0; 
				v=FindInKeyWordTab(token); 
				m_tCifa[m_ntCifaLen]=new CifaResult; 
				m_tCifa[m_ntCifaLen]->value=0; 
				m_tCifa[m_ntCifaLen]->type=v; 
				::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
				m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
				m_ntCifaLen++; 
				NextCh(); 
			} 
			break; 
		default: 
			token[0]=GetCurCh(); 
			token[1]=0; 
			m_tCifa[m_ntCifaLen]=new CifaResult; 
			m_tCifa[m_ntCifaLen]->value=2; 
			m_tCifa[m_ntCifaLen]->type=0; 
			::strcpy(m_tCifa[m_ntCifaLen]->text,token); 
			m_tCifa[m_ntCifaLen]->address=m_pCurCh; 
			m_ntCifaLen++; 
			NextCh(); 
		}//switch 
		if (m_ntCifaLen==LEX_DUAD_TABLE_LEN-2)//out of table space 
		{ 
			m_tCifa[m_ntCifaLen]=new CifaResult; 
			m_tCifa[m_ntCifaLen]->value=99; 
			m_tCifa[m_ntCifaLen]->type=0; 
			::strcpy(m_tCifa[m_ntCifaLen]->text,""); 
			m_tCifa[m_ntCifaLen]->address=m_pCurCh-1; 
			m_ntCifaLen++; 
			break; 
		} 
	}//GetSYM 
	m_tCifa[m_ntCifaLen]=new CifaResult; 
	m_tCifa[m_ntCifaLen]->value=0; 
	m_tCifa[m_ntCifaLen]->type=-1;//end node 
	::strcpy(m_tCifa[m_ntCifaLen]->text,""); 
	m_tCifa[m_ntCifaLen]->address=0; 
	m_ntCifaLen++; 
	return; 
} 
 
int CCompiler::FindInKeyWordTab(char * a) 
{ 
	for (int i=0;itype==1) 
		{ 
			v++; 
			if (!::stricmp(m_tCifa[i]->text,a)) 
				return m_tCifa[i]->value; 
		} 
	} 
	return v; 
} 
 
void CCompiler::YuFaFengXi() 
{ 
	if (m_ntCifaLen==0) return;//未进行词法分析 
	m_pCurSym=0; 
	p_ChengXu(); 
	m_Interface.ErrorAddress=m_nErrorAddress; 
	m_Interface.ErrorNumber=m_nErrorNum; 
	return; 
} 
 
int CCompiler::p_ChengXu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 3://program 
		break; 
	default: 
		m_nErrorNum=3; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=4; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 30://; 
		break; 
	default: 
		m_nErrorNum=5; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_ChengXuTi()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 31://. 
		break; 
	default: 
		m_nErrorNum=6; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case -1://end of cifa 
		break; 
	default: 
		m_nErrorNum=96; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	m_nErrorNum=0;//Successful 
	m_nErrorAddress=m_pCurSym; 
	return TRUE; 
} 
 
int CCompiler::p_ChengXuTi() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
	case 15://real 
	case 5://procedure 
		if (!p_ShuoMingChuan()) return FALSE; 
		switch (GetCurSym()->type) 
		{ 
		case 30://; 
			break; 
		default: 
			m_nErrorNum=5; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		NextSym(); 
		break; 
	case 6://begin 
		break; 
	default: 
		m_nErrorNum=7; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 6://begin 
		break; 
	default: 
		m_nErrorNum=8; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_YuJuChuan()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 7://end 
		break; 
	default: 
		m_nErrorNum=10; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::p_ShuoMingChuan() 
{ 
	if (!p_ShuoMing()) return FALSE; 
	while (GetCurSym()->type==30  
		&& GetNextSym()->type!=6)//; begin 
	{ 
		NextSym(); 
		if (!p_ShuoMing()) return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_ShuoMing() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
	case 15://real 
		if (!p_JianBianShuoMing()) return FALSE; 
		break; 
	case 5://procedure 
		if (!p_GuoChengShuoMing()) return FALSE; 
		break; 
	default: 
		m_nErrorNum=11; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_JianBianShuoMing() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
	case 15://real 
		break; 
	default: 
		m_nErrorNum=12; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=14; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	while (GetCurSym()->type==32) 
	{ 
		NextSym(); 
		switch (GetCurSym()->type) 
		{ 
		case 1://id 
			break; 
		default: 
			m_nErrorNum=14; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		NextSym(); 
	} 
	return TRUE; 
} 
 
int CCompiler::p_GuoChengShuoMing() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 5://procedure 
		break; 
	default: 
		m_nErrorNum=15; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=13; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		if (!p_XingChanBuFeng()) return FALSE; 
		break; 
	default: 
		; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 30://; 
		break; 
	default: 
		m_nErrorNum=5; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_ChengXuTi()) return FALSE; 
	return TRUE; 
} 
 
int CCompiler::p_XingChanBuFeng() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		break; 
	default: 
		m_nErrorNum=16; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_XingChan()) return FALSE; 
	while (GetCurSym()->type==30) 
	{ 
		NextSym(); 
		if (!p_XingChan()) return FALSE; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 34://) 
		break; 
	default: 
		m_nErrorNum=17; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::p_XingChan() 
{ 
	if (GetCurSym()->type==4)//var 
		NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=18; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	while (GetCurSym()->type==32)//, 
	{ 
		NextSym(); 
		switch (GetCurSym()->type) 
		{ 
		case 1://id 
			break; 
		default: 
			m_nErrorNum=18; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		NextSym(); 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 35://: 
		break; 
	default: 
		m_nErrorNum=19; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
	case 15://real 
		break; 
	default: 
		m_nErrorNum=12; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::p_YuJuChuan() 
{ 
	if (!p_YuJu()) return FALSE; 
	while (GetCurSym()->type==30)//; 
	{ 
		NextSym(); 
		if (!p_YuJu()) return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_YuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 6://begin 
		if (!p_FuHeYuJu()) return FALSE; 
		break; 
	case 1://id 
		if (!p_FuZhiYuJu()) return FALSE; 
		break; 
	case 8://if 
		if (!p_TiaoJianYuJu()) return FALSE; 
		break; 
	case 11://while 
		if (!p_XunHuanYuJu()) return FALSE; 
		break; 
	case 13://call 
		if (!p_GuoChengYuJu()) return FALSE; 
		break; 
	default: 
		m_nErrorNum=9; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_FuHeYuJu()//复合语句 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 6://begin 
		break; 
	default: 
		m_nErrorNum=8; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_YuJuChuan()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 7://end 
		break; 
	default: 
		m_nErrorNum=10; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::p_FuZhiYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=20; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 29://:= 
		break; 
	default: 
		m_nErrorNum=21; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_BiaoDaShi()) return FALSE; 
	return TRUE; 
} 
 
int CCompiler::p_TiaoJianYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 8://if 
		break; 
	default: 
		m_nErrorNum=22; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_BuErBiaoDaShi()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 9://then 
		break; 
	default: 
		m_nErrorNum=23; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_YuJu()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 10://else 
		break; 
	default: 
		return TRUE; 
	} 
	NextSym(); 
	if (!p_YuJu()) return FALSE; 
	return TRUE; 
} 
 
int CCompiler::p_XunHuanYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 11://while 
		break; 
	default: 
		m_nErrorNum=24; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_BuErBiaoDaShi()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 12://do 
		break; 
	default: 
		m_nErrorNum=25; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_YuJu()) return FALSE; 
	return TRUE; 
} 
 
int CCompiler::p_GuoChengYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 13://call 
		break; 
	default: 
		m_nErrorNum=26; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=27; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		break; 
	default: 
		return TRUE; 
	} 
	if (!p_ShiChanBiao()) return FALSE; 
	return TRUE; 
} 
 
int CCompiler::p_ShiChanBiao() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		break; 
	default: 
		m_nErrorNum=16; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!p_BiaoDaShi()) return FALSE; 
	while (GetCurSym()->type==32)//, 
	{ 
		NextSym(); 
		if (!p_BiaoDaShi()) return FALSE; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 34://) 
		break; 
	default: 
		m_nErrorNum=17; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::p_BiaoDaShi() 
{ 
	if (!p_Xiang()) return FALSE; 
	while (GetCurSym()->type==16)//+ 
	{ 
		NextSym(); 
		if (!p_Xiang()) return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_Xiang() 
{ 
	if (!p_YingZhi()) return FALSE; 
	while (GetCurSym()->type==18)//* 
	{ 
		NextSym(); 
		if (!p_YingZhi()) return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_YingZhi() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		NextSym(); 
		break; 
	case 2://num 
		NextSym(); 
		break; 
	case 33://( 
		NextSym(); 
		if (!p_BiaoDaShi()) return FALSE; 
		switch (GetCurSym()->type) 
		{ 
		case 34://) 
			break; 
		default: 
			m_nErrorNum=17; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		NextSym(); 
		break; 
	default: 
		m_nErrorNum=28; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_BuErBiaoDaShi() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 20://~ 
		NextSym(); 
		if (!p_BuErBiaoDaShi()) return FALSE; 
		break; 
	case 33://( 
	case 1://id 
	case 2://num 
		if (!p_GuanXiBiaoDaShi()) return FALSE; 
		while (GetCurSym()->type==21 || GetCurSym()->type==22) 
		{ 
			NextSym(); 
			if (!p_BuErBiaoDaShi()) return FALSE; 
		} 
		break; 
	default: 
		m_nErrorNum=29; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::p_GuanXiBiaoDaShi() 
{ 
	if (!p_BiaoDaShi()) return FALSE; 
	if (!p_GuanXi()) return FALSE; 
	if (!p_BiaoDaShi()) return FALSE; 
	return TRUE; 
} 
 
int CCompiler::p_GuanXi() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 23://< 
	case 24://<= 
	case 25://> 
	case 26://>= 
	case 27://= 
	case 28://<> 
		break; 
	default: 
		m_nErrorNum=30; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
void CCompiler::Initial() 
{ 
	::strcpy(m_QuadOpCodeTable[0], "_End_"); 
	::strcpy(m_QuadOpCodeTable[1], "in"); 
	::strcpy(m_QuadOpCodeTable[2], "call"); 
	::strcpy(m_QuadOpCodeTable[3], "out"); 
	::strcpy(m_QuadOpCodeTable[4], "ret"); 
	::strcpy(m_QuadOpCodeTable[5], ":=I"); 
	::strcpy(m_QuadOpCodeTable[6], ":=R"); 
	::strcpy(m_QuadOpCodeTable[7], "par"); 
	::strcpy(m_QuadOpCodeTable[8], "valueI"); 
	::strcpy(m_QuadOpCodeTable[9], "valueR"); 
	::strcpy(m_QuadOpCodeTable[10],"addr"); 
	::strcpy(m_QuadOpCodeTable[11],"j"); 
	::strcpy(m_QuadOpCodeTable[12],"j<"); 
	::strcpy(m_QuadOpCodeTable[13],"j<="); 
	::strcpy(m_QuadOpCodeTable[14],"j>"); 
	::strcpy(m_QuadOpCodeTable[15],"j>="); 
	::strcpy(m_QuadOpCodeTable[16],"j="); 
	::strcpy(m_QuadOpCodeTable[17],"j<>"); 
	::strcpy(m_QuadOpCodeTable[18],"`"); 
	::strcpy(m_QuadOpCodeTable[19],"+I"); 
	::strcpy(m_QuadOpCodeTable[20],"+R"); 
	::strcpy(m_QuadOpCodeTable[21],"*I"); 
	::strcpy(m_QuadOpCodeTable[22],"*R"); 
	::strcpy(m_QuadOpCodeTable[23],"`"); 
	::strcpy(m_QuadOpCodeTable[24],"`"); 
	::strcpy(m_QuadOpCodeTable[25],"`"); 
	::strcpy(m_QuadOpCodeTable[26],"`"); 
	::strcpy(m_QuadOpCodeTable[27],"`"); 
	::strcpy(m_QuadOpCodeTable[28],"`"); 
	::strcpy(m_QuadOpCodeTable[29],"_Error_"); 
	::strcpy(m_tKeyWord[0],""); 
	::strcpy(m_tKeyWord[1],"");//标识符 
	::strcpy(m_tKeyWord[2],"");//正整数 
	::strcpy(m_tKeyWord[3],"program"); 
	::strcpy(m_tKeyWord[4],"var"); 
	::strcpy(m_tKeyWord[5],"procedure"); 
	::strcpy(m_tKeyWord[6],"begin"); 
	::strcpy(m_tKeyWord[7],"end"); 
	::strcpy(m_tKeyWord[8],"if"); 
	::strcpy(m_tKeyWord[9],"then"); 
	::strcpy(m_tKeyWord[10],"else"); 
	::strcpy(m_tKeyWord[11],"while"); 
	::strcpy(m_tKeyWord[12],"do"); 
	::strcpy(m_tKeyWord[13],"call"); 
	::strcpy(m_tKeyWord[14],"integer"); 
	::strcpy(m_tKeyWord[15],"real"); 
	::strcpy(m_tKeyWord[16],"+"); 
	::strcpy(m_tKeyWord[17],"-"); 
	::strcpy(m_tKeyWord[18],"*"); 
	::strcpy(m_tKeyWord[19],"/"); 
	::strcpy(m_tKeyWord[20],"~"); 
	::strcpy(m_tKeyWord[21],"&"); 
	::strcpy(m_tKeyWord[22],"|"); 
	::strcpy(m_tKeyWord[23],"<"); 
	::strcpy(m_tKeyWord[24],"<="); 
	::strcpy(m_tKeyWord[25],">"); 
	::strcpy(m_tKeyWord[26],">="); 
	::strcpy(m_tKeyWord[27],"="); 
	::strcpy(m_tKeyWord[28],"<>"); 
	::strcpy(m_tKeyWord[29],":="); 
	::strcpy(m_tKeyWord[30],";"); 
	::strcpy(m_tKeyWord[31],"."); 
	::strcpy(m_tKeyWord[32],","); 
	::strcpy(m_tKeyWord[33],"("); 
	::strcpy(m_tKeyWord[34],")"); 
	::strcpy(m_tKeyWord[35],":"); 
	::strcpy(m_tKeyWord[36],"/*"); 
	::strcpy(m_tKeyWord[37],"*/"); 
	::strcpy(m_tKeyWord[38],""); 
	::strcpy(m_tKeyWord[39],""); 
	::strcpy(m_tKeyWord[40],""); 
	::strcpy(m_tKeyWord[41],""); 
	::strcpy(m_tKeyWord[42],""); 
	::strcpy(m_tKeyWord[43],""); 
	::strcpy(m_tKeyWord[44],""); 
	::strcpy(m_tKeyWord[45],""); 
	::strcpy(m_tKeyWord[46],""); 
	::strcpy(m_tKeyWord[47],""); 
	::strcpy(m_tKeyWord[48],""); 
	::strcpy(m_tKeyWord[49],""); 
	::strcpy(m_tErrorMessage[0],"正确!"); 
	::strcpy(m_tErrorMessage[1],"数字位数过长!"); 
	::strcpy(m_tErrorMessage[2],"非法字符!"); 
	::strcpy(m_tErrorMessage[3],"缺少保留字“ program ”!"); 
	::strcpy(m_tErrorMessage[4],"program 后缺少标识符!"); 
	::strcpy(m_tErrorMessage[5],"缺少“ ; ”符号!"); 
	::strcpy(m_tErrorMessage[6],"缺少程序结束符“ . ”符号!"); 
	::strcpy(m_tErrorMessage[7],"缺少《程序体》,应为 begin,integer,real,procedure"); 
	::strcpy(m_tErrorMessage[8],"缺少保留字“ begin ”!"); 
	::strcpy(m_tErrorMessage[9],"缺少《语句》,应为 begin,ID,if,while,call"); 
	::strcpy(m_tErrorMessage[10],"缺少保留字“ end ”!"); 
	::strcpy(m_tErrorMessage[11],"缺少《说明》,应为 integer,real,procedure"); 
	::strcpy(m_tErrorMessage[12],"缺少保留字 integer 或 real!"); 
	::strcpy(m_tErrorMessage[13],"procedure 后缺少标识符!"); 
	::strcpy(m_tErrorMessage[14],"简单变量说明后缺少标识符!"); 
	::strcpy(m_tErrorMessage[15],"缺少保留字“ procedure ”!"); 
	::strcpy(m_tErrorMessage[16],"缺少 “ ( ”符号!"); 
	::strcpy(m_tErrorMessage[17],"缺少 “ ) ”符号!"); 
	::strcpy(m_tErrorMessage[18],"缺少形参标识符 !"); 
	::strcpy(m_tErrorMessage[19],"缺少 “ : ”符号!"); 
	::strcpy(m_tErrorMessage[20],"缺少标识符!"); 
	::strcpy(m_tErrorMessage[21],"缺少赋值符号“ := ”!"); 
	::strcpy(m_tErrorMessage[22],"缺少保留字“ if ”!"); 
	::strcpy(m_tErrorMessage[23],"缺少保留字“ then ”!"); 
	::strcpy(m_tErrorMessage[24],"缺少保留字“ while ”!"); 
	::strcpy(m_tErrorMessage[25],"缺少保留字“ do ”!"); 
	::strcpy(m_tErrorMessage[26],"缺少保留字“ call ”!"); 
	::strcpy(m_tErrorMessage[27],"缺少被调过程名标识符!"); 
	::strcpy(m_tErrorMessage[28],"缺少《因子》,应为 (,ID,NUMBER"); 
	::strcpy(m_tErrorMessage[29],"缺少《布尔表达式》,应为 ~,(,ID,NUMBER"); 
	::strcpy(m_tErrorMessage[30],"缺少《关系》!"); 
	::strcpy(m_tErrorMessage[31],"变量名不能和过程名相同!"); 
	::strcpy(m_tErrorMessage[32],"标识符重复定义!"); 
	::strcpy(m_tErrorMessage[33],"未定义标识符!"); 
	::strcpy(m_tErrorMessage[34],"不能直接引用过程名!"); 
	::strcpy(m_tErrorMessage[35],"不能从real转换为integer类型!"); 
	::strcpy(m_tErrorMessage[36],"不能用常数作实参!"); 
	::strcpy(m_tErrorMessage[37],"变参应为变量!"); 
	::strcpy(m_tErrorMessage[38],"实参个数不足!"); 
	::strcpy(m_tErrorMessage[39],"只有integer和integer才能比较!"); 
	::strcpy(m_tErrorMessage[40],"不能这样调用过程!"); 
	::strcpy(m_tErrorMessage[41],""); 
	::strcpy(m_tErrorMessage[42],""); 
	::strcpy(m_tErrorMessage[43],""); 
	::strcpy(m_tErrorMessage[96],"源程序结束符 end. 后还有多余单词!"); 
	::strcpy(m_tErrorMessage[97],"语法错误太多,终止语法分析!"); 
	::strcpy(m_tErrorMessage[98],"源程序不正常结束!"); 
	::strcpy(m_tErrorMessage[99],"内存不足!词法分析终止!"); 
} 
 
BOOL CCompiler::isalpha(char a) 
{ 
	return ((a>='a'&&a<='z')||(a>='A'&&a<='Z')); 
} 
 
BOOL CCompiler::isalnum(char a) 
{ 
	return ((a>='a'&&a<='z')||(a>='A'&&a<='Z')||(a>='0'&&a<='9')); 
} 
 
BOOL CCompiler::isdigit(char a) 
{ 
	return (a>='0'&&a<='9'); 
} 
 
CifaResult * CCompiler::GetCurSym() 
{ 
	return m_tCifa[m_pCurSym]; 
} 
 
void CCompiler::NextSym() 
{ 
	m_pCurSym++; 
} 
 
CifaResult * CCompiler::GetSym() 
{ 
	return m_tCifa[m_pCurSym++]; 
} 
 
CifaResult * CCompiler::GetNextSym() 
{ 
	return m_tCifa[m_pCurSym+1]; 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void CCompiler::YuYiFengXi() 
{ 
	if (m_ntCifaLen==0) return;//Cifa not do 
	yuyivar.currbl=0; 
	yuyivar.lasent=0; 
	yuyivar.lastbl=0; 
	yuyivar.nxq=0; 
	yuyivar.tempp=0; 
	gen("",0,0,0,0,0,0);//idtab start from 1 
	addid("",0,0,0);//idtab start from 1 
//temptab and leveltab start from 0 
	m_pCurSym=0;//* <-- 
	r_ChengXu(); 
	gen("_End_",0,0,0,0,0,0);//end note 
	m_Interface.ErrorAddress=m_nErrorAddress; 
	m_Interface.ErrorNumber=m_nErrorNum; 
	return; 
} 
 
int CCompiler::r_ChengXu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 3://program 
		break; 
	default: 
		m_nErrorNum=3; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=4; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	leveltab[yuyivar.currbl].lnp=yuyivar.nxq+1; 
	leveltab[yuyivar.currbl].lnum=0; 
	::strcpy(leveltab[yuyivar.currbl].name,GetCurSym()->text); 
	leveltab[yuyivar.currbl].outern=0; 
	leveltab[yuyivar.currbl].parnum=0; 
	leveltab[yuyivar.currbl].pointer=yuyivar.lasent; 
	leveltab[yuyivar.currbl].recl=5; 
	leveltab[yuyivar.currbl].varnum=0; 
	leveltab[yuyivar.currbl].temp=yuyivar.tempp; 
	yuyivar.lastbl++; 
	gen("call",1,0,1,0,2,2); 
	int link=yuyivar.nxq; 
	gen("in",0,0,0,0,0,0); 
//yy end 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 30://; 
		break; 
	default: 
		m_nErrorNum=5; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_ChengXuTi()) return FALSE; 
//yy 
	backpatch(link,2,2,leveltab[yuyivar.currbl].recl); 
	gen("out",0,0,0,0,0,0); 
	gen("ret",0,0,0,0,0,0); 
	yuyivar.currbl=leveltab[yuyivar.currbl].outern; 
	yuyivar.tempp=leveltab[yuyivar.currbl].temp; 
//yy end 
	switch (GetCurSym()->type) 
	{ 
	case 31://. 
		break; 
	default: 
		m_nErrorNum=6; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case -1://end of cifa 
		break; 
	default: 
		m_nErrorNum=96; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	m_nErrorNum=0; 
	m_nErrorAddress=m_pCurSym; 
	return TRUE; 
} 
 
int CCompiler::r_ChengXuTi() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
	case 15://real 
	case 5://procedure 
		if (!r_ShuoMingChuan()) return FALSE; 
		switch (GetCurSym()->type) 
		{ 
		case 30://; 
			break; 
		default: 
			m_nErrorNum=5; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		NextSym(); 
		break; 
	case 6://begin 
		break; 
	default: 
		m_nErrorNum=7; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 6://begin 
		break; 
	default: 
		m_nErrorNum=8; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_YuJuChuan()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 7://end 
		break; 
	default: 
		m_nErrorNum=10; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::r_ShuoMingChuan() 
{ 
	if (!r_ShuoMing()) return FALSE; 
	while (GetCurSym()->type==30  
		&& GetNextSym()->type!=6)//; begin 
	{ 
		NextSym(); 
		if (!r_ShuoMing()) return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::r_ShuoMing() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
	case 15://real 
		if (!r_JianBianShuoMing()) return FALSE; 
		break; 
	case 5://procedure 
		if (!r_GuoChengShuoMing()) return FALSE; 
		break; 
	default: 
		m_nErrorNum=11; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::r_JianBianShuoMing() 
{ 
	int typ;//yy 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
		typ=1;//yy 
		break; 
	case 15://real 
		typ=2;//yy 
		break; 
	default: 
		m_nErrorNum=12; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=14; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	switch (lookupv(GetCurSym()->text,yuyivar.currbl)) 
	{ 
	case -1: 
		m_nErrorNum=31; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	case 0: 
		addid(GetCurSym()->text,typ,1,leveltab[yuyivar.currbl].recl); 
		leveltab[yuyivar.currbl].varnum++; 
		leveltab[yuyivar.currbl].recl+=typ; 
		break; 
	default: 
		m_nErrorNum=32; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy end 
	NextSym(); 
	while (GetCurSym()->type==32) //, 
	{ 
		NextSym(); 
		switch (GetCurSym()->type) 
		{ 
		case 1://id 
			break; 
		default: 
			m_nErrorNum=14; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
//yy 
		switch (lookupv(GetCurSym()->text,yuyivar.currbl)) 
		{ 
		case -1: 
			m_nErrorNum=31; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		case 0: 
			addid(GetCurSym()->text,typ,1,leveltab[yuyivar.currbl].recl); 
			leveltab[yuyivar.currbl].varnum++; 
			leveltab[yuyivar.currbl].recl+=typ; 
			break; 
		default: 
			m_nErrorNum=32; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
//yy end 
		NextSym(); 
	} 
	return TRUE; 
} 
 
int CCompiler::r_GuoChengShuoMing() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 5://procedure 
		break; 
	default: 
		m_nErrorNum=15; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=13; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	int link1=yuyivar.nxq; 
	gen("j",0,0,0,0,0,0); 
	leveltab[yuyivar.lastbl].lnp=yuyivar.nxq; 
	leveltab[yuyivar.lastbl].lnum=yuyivar.lastbl; 
	::strcpy(leveltab[yuyivar.lastbl].name,GetCurSym()->text); 
	leveltab[yuyivar.lastbl].outern=yuyivar.currbl; 
	leveltab[yuyivar.lastbl].parnum=0; 
	leveltab[yuyivar.lastbl].pointer=yuyivar.lasent; 
	leveltab[yuyivar.lastbl].recl=4; 
	leveltab[yuyivar.lastbl].temp=yuyivar.tempp; 
	leveltab[yuyivar.lastbl].varnum=0; 
	yuyivar.currbl=yuyivar.lastbl; 
	int v=lookupp(GetCurSym()->text); 
	yuyivar.lastbl++; 
	if (v!=-1) 
	{ 
		m_nErrorNum=32; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	int link2=yuyivar.nxq; 
	gen("in",0,0,0,0,0,0); 
//yy end 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		if (!r_XingChanBuFeng()) return FALSE; 
		break; 
	default: 
		; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 30://; 
		break; 
	default: 
		m_nErrorNum=5; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_ChengXuTi()) return FALSE; 
//yy 
	backpatch(link2,2,2,leveltab[yuyivar.currbl].recl); 
	gen("out",0,0,0,0,0,0); 
	gen("ret",0,0,0,0,0,0); 
	backpatch(link1,4,2,yuyivar.nxq); 
	yuyivar.currbl=leveltab[yuyivar.currbl].outern; 
	yuyivar.tempp=leveltab[yuyivar.currbl].temp; 
//yy end 
	return TRUE; 
} 
 
int CCompiler::r_XingChanBuFeng() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		break; 
	default: 
		m_nErrorNum=16; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_XingChan()) return FALSE; 
	while (GetCurSym()->type==30) 
	{ 
		NextSym(); 
		if (!r_XingChan()) return FALSE; 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 34://) 
		break; 
	default: 
		m_nErrorNum=17; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::r_XingChan() 
{ 
	int parn;//yy 
	if (GetCurSym()->type==4)//var 
	{ 
		NextSym();parn=1;//yy 
	} 
	else parn=0;//yy 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=18; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	if (lookupv(GetCurSym()->text,yuyivar.currbl)!=0) 
	{ 
		m_nErrorNum=32; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	int link=yuyivar.lasent; 
	addid(GetCurSym()->text,0,3+parn,0); 
	leveltab[yuyivar.currbl].parnum++; 
//yy end 
	NextSym(); 
	while (GetCurSym()->type==32)//, 
	{ 
		NextSym(); 
		switch (GetCurSym()->type) 
		{ 
		case 1://id 
			break; 
		default: 
			m_nErrorNum=18; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
//yy 
		if (lookupv(GetCurSym()->text,yuyivar.currbl)!=0) 
		{ 
			m_nErrorNum=32; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		addid(GetCurSym()->text,0,3+parn,0); 
		leveltab[yuyivar.currbl].parnum++; 
//yy end 
		NextSym(); 
	} 
	switch (GetCurSym()->type) 
	{ 
	case 35://: 
		break; 
	default: 
		m_nErrorNum=19; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	int typ;//yy 
	switch (GetCurSym()->type) 
	{ 
	case 14://integer 
		typ=1;//yy 
		break; 
	case 15://real 
		typ=2;//yy 
		break; 
	default: 
		m_nErrorNum=12; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
//yy 
	for (int i=link;itype==30)//; 
	{ 
		NextSym(); 
		if (!r_YuJu()) return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::r_YuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 6://begin 
		if (!r_FuHeYuJu()) return FALSE; 
		break; 
	case 1://id 
		if (!r_FuZhiYuJu()) return FALSE; 
		break; 
	case 8://if 
		if (!r_TiaoJianYuJu()) return FALSE; 
		break; 
	case 11://while 
		if (!r_XunHuanYuJu()) return FALSE; 
		break; 
	case 13://call 
		if (!r_GuoChengYuJu()) return FALSE; 
		break; 
	default: 
		m_nErrorNum=9; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::r_FuHeYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 6://begin 
		break; 
	default: 
		m_nErrorNum=8; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_YuJuChuan()) return FALSE; 
	switch (GetCurSym()->type) 
	{ 
	case 7://end 
		break; 
	default: 
		m_nErrorNum=10; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::r_FuZhiYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=20; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	int idlevel=yuyivar.currbl; 
	int idpoint=lookupv2(GetCurSym()->text,idlevel); 
	if (idpoint==0) 
	{ 
		m_nErrorNum=33; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	if (idpoint==-1) 
	{ 
		m_nErrorNum=34; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	int t1=idtab[idpoint].typ; 
	int k1=idtab[idpoint].addr; 
	int i1; 
	if (idlevel==yuyivar.currbl) 
	{ 
		if (idtab[idpoint].kind==4) i1=5; 
		else i1=4; 
	} 
	else 
	{ 
		i1=idlevel+6; 
	} 
//yy end 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 29://:= 
		break; 
	default: 
		m_nErrorNum=21; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_BiaoDaShi()) return FALSE; 
//yy 
	int t2; 
	int k2; 
	int i2=yuyivalue.Etyp; 
	int j2=yuyivalue.Evalue; 
	if (i2==1) 
	{ 
		k2=j2; 
		t2=1; 
	} 
	else if (i2==2) 
	{ 
		k2=temptab[j2].taddr; 
		t2=temptab[j2].typ; 
		i2=3; 
	} 
	else 
	{ 
		k2=idtab[j2].addr; 
		t2=idtab[j2].typ; 
		i2+=1; 
	} 
	if (t1type) 
	{ 
	case 8://if 
		break; 
	default: 
		m_nErrorNum=22; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_BuErBiaoDaShi()) return FALSE; 
//yy 
	int TCexit=yuyivalue.TC; 
	int FCexit=yuyivalue.FC; 
	backpatch(TCexit,4,2,yuyivar.nxq); 
//yy end 
	switch (GetCurSym()->type) 
	{ 
	case 9://then 
		break; 
	default: 
		m_nErrorNum=23; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_YuJu()) return FALSE; 
//yy 
	int link=yuyivar.nxq; 
	gen("j",0,0,0,0,0,0); 
//yy end 
	switch (GetCurSym()->type) 
	{ 
	case 10://else 
		NextSym(); 
		backpatch(FCexit,4,2,yuyivar.nxq);//yy 
		if (!r_YuJu()) return FALSE; 
		break; 
	default: 
		backpatch(FCexit,4,2,yuyivar.nxq);//yy 
	} 
	backpatch(link,4,2,yuyivar.nxq);//yy 
	return TRUE; 
} 
 
int CCompiler::r_XunHuanYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 11://while 
		break; 
	default: 
		m_nErrorNum=24; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	int p=yuyivar.nxq;//yy 
	if (!r_BuErBiaoDaShi()) return FALSE; 
//yy 
	int TCexit=yuyivalue.TC; 
	int FCexit=yuyivalue.FC; 
	backpatch(TCexit,4,2,yuyivar.nxq); 
//yy end 
	switch (GetCurSym()->type) 
	{ 
	case 12://do 
		break; 
	default: 
		m_nErrorNum=25; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_YuJu()) return FALSE; 
//yy 
	gen("j",0,0,0,0,2,p); 
	backpatch(FCexit,4,2,yuyivar.nxq); 
//yy end 
	return TRUE; 
} 
 
int CCompiler::r_GuoChengYuJu() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 13://call 
		break; 
	default: 
		m_nErrorNum=26; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
		break; 
	default: 
		m_nErrorNum=27; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	int level=lookupp(GetCurSym()->text); 
	yuyivalue.disp=level; 
	if (level>yuyivar.currbl+1) 
	{ 
		m_nErrorNum=40; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy end 
	NextSym(); 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		break; 
	default: 
		return TRUE; 
	} 
	if (!r_ShiChanBiao()) return FALSE; 
//yy 
	gen("call",1,leveltab[level].parnum,1,level,2,leveltab[level].lnp); 
//yy end 
	return TRUE; 
} 
 
int CCompiler::r_ShiChanBiao() 
{ 
//yy 
	int pp=yuyivalue.disp; 
	int parp=leveltab[pp].pointer; 
	int n=0; 
	int i,j,k,t; 
//yy end 
	switch (GetCurSym()->type) 
	{ 
	case 33://( 
		break; 
	default: 
		m_nErrorNum=16; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	if (!r_BiaoDaShi()) return FALSE; 
//yy 
	if (n<=leveltab[pp].parnum) 
	{ 
		i=yuyivalue.Etyp; 
		j=yuyivalue.Evalue; 
		switch (i) 
		{ 
		case 1: 
			m_nErrorNum=36; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		case 2: 
			k=temptab[j].taddr; 
			t=temptab[j].typ; 
			i++; 
			break; 
		default: 
			k=idtab[j].addr; 
			t=idtab[j].typ; 
			i++; 
		} 
		if ((i==3) && (idtab[parp].kind==4)) 
		{ 
			m_nErrorNum=37; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		if (t>idtab[parp].typ) 
		{ 
			m_nErrorNum=35; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		gen("par",i,k,0,0,0,0); 
		if (i==3) temptab[j].used=FALSE; 
		n++;parp++; 
	} 
//yy end 
	while (GetCurSym()->type==32)//, 
	{ 
		NextSym(); 
		if (!r_BiaoDaShi()) return FALSE; 
//yy 
		if (n<=leveltab[pp].parnum) 
		{ 
			i=yuyivalue.Etyp; 
			j=yuyivalue.Evalue; 
			switch (i) 
			{ 
			case 1: 
				m_nErrorNum=36; 
				m_nErrorAddress=m_pCurSym; 
				return FALSE; 
			case 2: 
				k=temptab[j].taddr; 
				t=temptab[j].typ; 
				i++; 
				break; 
			default: 
				k=idtab[j].addr; 
				t=idtab[j].typ; 
				i++; 
			} 
			if ((i==3) && (idtab[parp].kind==4)) 
			{ 
				m_nErrorNum=37; 
				m_nErrorAddress=m_pCurSym; 
				return FALSE; 
			} 
			if (t>idtab[parp].typ) 
			{ 
				m_nErrorNum=35; 
				m_nErrorAddress=m_pCurSym; 
				return FALSE; 
			} 
			gen("par",i,k,0,0,0,0); 
			if (i==3) temptab[j].used=FALSE; 
			n++;parp++; 
		} 
//yy end 
	} 
//yy 
	if (ntype) 
	{ 
	case 34://) 
		break; 
	default: 
		m_nErrorNum=17; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	NextSym(); 
	return TRUE; 
} 
 
int CCompiler::r_BiaoDaShi() 
{ 
	int i1,i2,j1,j2,t1,t2,k1,k2,i,j,t,k; 
	if (!r_Xiang()) return FALSE; 
//yy 
	i=yuyivalue.Etyp; 
	j=yuyivalue.Evalue; 
	i1=i;j1=j; 
	switch (i1) 
	{ 
	case 1: 
		t1=1;k1=j1;break; 
	case 2: 
		t1=temptab[j1].typ; 
		k1=temptab[j1].taddr; 
		break; 
	default : 
		t1=idtab[j1].typ; 
		k1=idtab[j1].addr; 
	} 
//yy end 
	while (GetCurSym()->type==16)//+ 
	{ 
		NextSym(); 
		if (!r_Xiang()) return FALSE; 
//yy 
		i2=yuyivalue.Etyp; 
		j2=yuyivalue.Evalue; 
		switch (i2) 
		{ 
		case 1: 
			t2=1;k2=j2;break; 
		case 2: 
			t2=temptab[j2].typ; 
			k2=temptab[j2].taddr; 
			break; 
		default : 
			t2=idtab[j2].typ; 
			k2=idtab[j2].addr; 
		} 
		t=(t1>t2)?t1:t2; 
		j=newtemp(t); 
		k=temptab[j].taddr; 
		if (i1==1) 
			if (i2==1) 
				gen("+I",1,j1,1,j2,3,k); 
			else 
				if (t2==1) 
					gen("+I",1,j1,i2+1,k2,3,k); 
				else 
					gen("+R",1,j1,i2+1,k2,3,k); 
		else 
			if (i2==1) 
				if (t1==1) 
					gen("+I",i1+1,k1,1,j2,3,k); 
				else 
					gen("+R",i1+1,k1,1,j2,3,k); 
			else 
				if ((t1==1) && (t2==1)) 
					gen("+I",i1+1,k1,i2+1,k2,3,k); 
				else 
					gen("+R",i1+1,k1,i2+1,k2,3,k); 
		if (i1==2) temptab[j1].used=FALSE; 
		if (i2==2) temptab[j2].used=FALSE; 
		i=2; 
		i1=i;j1=j;t1=t;k1=k; 
//yy end 
	} 
//yy 
	yuyivalue.Etyp=i; 
	yuyivalue.Evalue=j; 
//yy end 
	return TRUE; 
} 
 
int CCompiler::r_Xiang() 
{ 
	int i1,i2,j1,j2,t1,t2,k1,k2,i,j,t,k; 
	if (!r_YingZhi()) return FALSE; 
//yy 
	i=yuyivalue.Etyp; 
	j=yuyivalue.Evalue; 
	i1=i;j1=j; 
	switch (i1) 
	{ 
	case 1: 
		t1=1;k1=j1;break; 
	case 2: 
		t1=temptab[j1].typ; 
		k1=temptab[j1].taddr; 
		break; 
	default : 
		t1=idtab[j1].typ; 
		k1=idtab[j1].addr; 
	} 
//yy end 
	while (GetCurSym()->type==18)//* 
	{ 
		NextSym(); 
		if (!r_YingZhi()) return FALSE; 
//yy 
		i2=yuyivalue.Etyp; 
		j2=yuyivalue.Evalue; 
		switch (i2) 
		{ 
		case 1: 
			t2=1;k2=j2;break; 
		case 2: 
			t2=temptab[j2].typ; 
			k2=temptab[j2].taddr; 
			break; 
		default : 
			t2=idtab[j2].typ; 
			k2=idtab[j2].addr; 
		} 
		t=(t1>t2)?t1:t2; 
		j=newtemp(t); 
		k=temptab[j].taddr; 
		if (i1==1) 
			if (i2==1) 
				gen("*I",1,j1,1,j2,3,k); 
			else 
				if (t2==1) 
					gen("*I",1,j1,i2+1,k2,3,k); 
				else 
					gen("*R",1,j1,i2+1,k2,3,k); 
		else 
			if (i2==1) 
				if (t1==1) 
					gen("*I",i1+1,k1,1,j2,3,k); 
				else 
					gen("*R",i1+1,k1,1,j2,3,k); 
			else 
				if ((t1==1) && (t2==1)) 
					gen("*I",i1+1,k1,i2+1,k2,3,k); 
				else 
					gen("*R",i1+1,k1,i2+1,k2,3,k); 
		if (i1==2) temptab[j1].used=FALSE; 
		if (i2==2) temptab[j2].used=FALSE; 
		i=2; 
		i1=i;j1=j;t1=t;k1=k; 
//yy end 
	} 
//yy 
	yuyivalue.Etyp=i; 
	yuyivalue.Evalue=j; 
//yy end 
	return TRUE; 
} 
 
int CCompiler::r_YingZhi() 
{ 
	int idlevel=yuyivar.currbl;//yy 
	int idpoint;//yy 
	switch (GetCurSym()->type) 
	{ 
	case 1://id 
//yy 
		idpoint=lookupv2(GetCurSym()->text,idlevel); 
		switch (idpoint) 
		{ 
		case -1: 
			m_nErrorNum=34; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		case 0: 
			m_nErrorNum=33; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		default: 
			if (idlevel==yuyivar.currbl) 
				if (idtab[idpoint].kind==4) yuyivalue.Etyp=4; 
				else yuyivalue.Etyp=3; 
			else yuyivalue.Etyp=idlevel+5; 
			yuyivalue.Evalue=idpoint; 
		} 
//yy end 
		NextSym(); 
		break; 
	case 2://num 
//yy 
		yuyivalue.Etyp=1; 
		yuyivalue.Evalue=GetCurSym()->value; 
//yy end 
		NextSym(); 
		break; 
	case 33://( 
		NextSym(); 
		if (!r_BiaoDaShi()) return FALSE; 
		switch (GetCurSym()->type) 
		{ 
		case 34://) 
			break; 
		default: 
			m_nErrorNum=17; 
			m_nErrorAddress=m_pCurSym; 
			return FALSE; 
		} 
		NextSym(); 
		break; 
	default: 
		m_nErrorNum=28; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::r_BuErBiaoDaShi() 
{ 
	int t; 
	int tc,fc; 
	switch (GetCurSym()->type) 
	{ 
	case 20://~ 
		NextSym(); 
		if (!r_BuErBiaoDaShi()) return FALSE; 
//yy 
		t=yuyivalue.TC; 
		yuyivalue.TC=yuyivalue.FC; 
		yuyivalue.FC=t; 
//yy end 
		break; 
	case 33://( 
	case 1://id 
	case 2://num 
		if (!r_GuanXiBiaoDaShi()) return FALSE; 
//yy 
		tc=yuyivalue.TC; 
		fc=yuyivalue.FC; 
//yy end 
		while (GetCurSym()->type==21 || GetCurSym()->type==22) 
		{ 
			if (GetCurSym()->type==21)//& 
			{ 
				NextSym(); 
				backpatch(tc,4,2,yuyivar.nxq);//yy 
				if (!r_BuErBiaoDaShi()) return FALSE; 
				tc=yuyivalue.TC;//yy 
				fc=merge(fc,yuyivalue.FC,4);//yy 
			} 
			else //| 
			{ 
				NextSym(); 
				backpatch(fc,4,2,yuyivar.nxq);//yy 
				if (!r_BuErBiaoDaShi()) return FALSE; 
				fc=yuyivalue.FC;//yy 
				tc=merge(tc,yuyivalue.TC,4);//yy 
			} 
		} 
//yy 
		yuyivalue.TC=tc; 
		yuyivalue.FC=fc; 
//yy end 
		break; 
	default: 
		m_nErrorNum=29; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	return TRUE; 
} 
 
int CCompiler::r_GuanXiBiaoDaShi() 
{ 
	int i1,i2,j1,j2,t1,t2,k1,k2,rop; 
	if (!r_BiaoDaShi()) return FALSE; 
//yy 
	i1=yuyivalue.Etyp; 
	j1=yuyivalue.Evalue; 
	switch (i1) 
	{ 
	case 1: 
		t1=1,k1=j1;break; 
	case 2: 
		t1=temptab[j1].typ; 
		k1=temptab[j1].taddr; 
		break; 
	default: 
		t1=idtab[j1].typ; 
		k1=idtab[j1].addr; 
	} 
//yy end 
	if (!r_GuanXi()) return FALSE; 
	rop=yuyivalue.Code;//yy 
	if (!r_BiaoDaShi()) return FALSE; 
//yy 
	i2=yuyivalue.Etyp; 
	j2=yuyivalue.Evalue; 
	switch (i2) 
	{ 
	case 1: 
		t2=1,k2=j2;break; 
	case 2: 
		t2=temptab[j2].typ; 
		k2=temptab[j2].taddr; 
		break; 
	default: 
		t2=idtab[j2].typ; 
		k2=idtab[j2].addr; 
	} 
	if ((t1!=1) || (t2!=1)) 
	{ 
		m_nErrorNum=39; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
	yuyivalue.TC=yuyivar.nxq; 
	if (i1!=1) i1++; 
	if (i2!=1) i2++; 
	gen(m_QuadOpCodeTable[rop],i1,k1,i2,k2,0,0); 
	yuyivalue.FC=yuyivar.nxq; 
	gen("j",0,0,0,0,0,0); 
	if (i1==3) temptab[j1].used=FALSE; 
	if (i2==3) temptab[j2].used=FALSE; 
//yy end 
	return TRUE; 
} 
 
int CCompiler::r_GuanXi() 
{ 
	switch (GetCurSym()->type) 
	{ 
	case 23://< 
	case 24://<= 
	case 25://> 
	case 26://>= 
	case 27://= 
	case 28://<> 
		break; 
	default: 
		m_nErrorNum=30; 
		m_nErrorAddress=m_pCurSym; 
		return FALSE; 
	} 
//yy 
	yuyivalue.Code=GetCurSym()->type-11; 
//yy end 
	NextSym(); 
	return TRUE; 
} 
 
void CCompiler::gen(char * op,int a1,int a2,int a3,int a4,int a5,int a6) 
{ 
	if (yuyivar.nxq>=QUAD_TABLE_LEN-1) return; 
	int r=29; 
	for (int i=0;i=ID_TABLE_LEN-1) return; 
	::strcpy(idtab[yuyivar.lasent].name,name); 
	idtab[yuyivar.lasent].typ=typ; 
	idtab[yuyivar.lasent].kind=kind; 
	idtab[yuyivar.lasent].addr=addr; 
	yuyivar.lasent++; 
} 
 
void CCompiler::backpatch(int link, int point, int v1, int v2) 
{ 
	if (link==0) return; 
	switch (point) 
	{ 
	case 2: 
		backpatch(quad[link].arg1.fl,point,v1,v2); 
		quad[link].arg1.fl=v1; 
		quad[link].arg1.flvalue=v2; 
		break; 
	case 3: 
		backpatch(quad[link].arg2.fl,point,v1,v2); 
		quad[link].arg2.fl=v1; 
		quad[link].arg2.flvalue=v2; 
		break; 
	case 4: 
		backpatch(quad[link].result.fl,point,v1,v2); 
		quad[link].result.fl=v1; 
		quad[link].result.flvalue=v2; 
		break; 
	default: 
		return; 
	} 
} 
 
int CCompiler::lookupv(char * idname, int idlevel) 
{ 
	if (!::stricmp(idname,leveltab[idlevel].name)) return -1; 
	int n=leveltab[idlevel].varnum+leveltab[idlevel].parnum; 
	int pointer=leveltab[idlevel].pointer; 
	for (int i=pointer;i<(pointer+n);i++) 
		if (!::stricmp(idname,idtab[i].name)) return i; 
	return 0; 
} 
 
int CCompiler::lookupp(char * id) 
{ 
	for (int i=0;i