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

📄 gcppparser.cpp

📁 一个非常有用的开源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			break;		if(pTok->Equals(".") && GetToken(1)->Equals(".") && GetToken(2)->Equals("."))		{			Advance();			Advance();			Advance();			hMethod.Get()->AddModifier(MM_VARARG);		}		else		{			GCppDeclaration* pVar = ParseDecl(true);			if(!pVar)				return NULL;			if(pVar->GetDeclType() != GCppDeclaration::VAR)			{				OnError(GetToken(0), "Expected a variable declaration");				return NULL;			}			hMethod.Get()->AddParameter((GCppVariable*)pVar);		}		pTok = GetToken(0);		if(pTok->Equals(","))			Advance();		else if(!pTok->Equals(")"))		{			OnError(pTok, "Expected a ',' or ')'");			return NULL;		}	}	if(!pTok->Equals(")"))	{		OnError(pTok, "expected a ')'");		return NULL;	}	Advance();	pTok = GetToken(0);	// Check for abstract "=0" suffix	if(pTok->Equals("="))	{		Advance(); // skip the '='		Advance(); // skip the '0'		hMethod.Get()->AddModifier(MM_ABSTRACT);		pTok = GetToken(0);	}	// Skip member initializers and base constructor calls	if(bConstructor)	{		while(true)		{			pTok = GetToken(0);			if(pTok->GetLength() <= 0 || pTok->Equals(";") || pTok->Equals("{"))				break;			Advance();		}	}	// Skip the body	if(pTok->Equals("{"))	{		if(!ParseMethodBody(hMethod.Get()))			return NULL;	}	return hMethod.Drop();}GCppType* GCppParser::ParseFunctionPointer(const char** ppName){	// Parse the return type	GCppType* pRetType = ParseTypeRef(false, false);	if(!pRetType)		return NULL;	GCppToken* pTok = GetToken(0);	if(!pTok->Equals("("))	{		OnError(pTok, "This doesn't look like the definition of a function pointer");		return NULL;	}	Advance(); // move past the "("	// Skip any modifiers	while(true)	{		pTok = GetToken(0);		if(pTok->Equals("*"))			break;		else if(pTok->GetLength() < 0 || pTok->Equals(")") || pTok->Equals(";"))		{			OnError(pTok, "This doesn't look like the definition of a function pointer");			return NULL;		}		Advance();	}	Advance(); // Move past the '*'	// Parse the name	pTok = GetToken(0);	char szTmp[8];	const char* pName;	int nNameLen;	if(pTok->Equals("("))	{		// no name is specified, so make a random name		GetRandomName(szTmp);		pName = szTmp;		nNameLen = 8;	}	else	{		pName = pTok->GetValue();		nNameLen = pTok->GetLength();		Advance();		pTok = GetToken(0);	}	*ppName = m_pStringHeap->Add(pName, nNameLen);	// Move past the ")"	if(!pTok->Equals(")"))	{		*ppName = NULL;		OnError(pTok, "Expected a ')'");		return NULL;	}	Advance(); // Move past the ")"	// Eat the parameters	pTok = GetToken(0);	if(!pTok->Equals("("))	{		*ppName = NULL;		OnError(pTok, "Expected a '(' -- possibly an extra semi-colon there");		return NULL;	}	Advance(); // Move past the "("	int nParams = 1;	while(nParams > 0)	{		pTok = GetToken(0);		if(pTok->Equals("("))			nParams++;		else if(pTok->Equals(")"))			nParams--;		Advance();	}	// Make a random name for the type	char szTmp2[8];	GetRandomName(szTmp2);	char* szTypeName = m_pStringHeap->Add(szTmp2, 8);	// Make the type and add it to the current scope	GCppType* pNewType = new GCppFuncPtr(szTypeName);	GetCurrentScope()->m_pTypes->Add(szTypeName, pNewType);	//if(GetCurrentFile()->IsProjectFile())	//	pNewType->SetDeclaredInProjectFile();	return pNewType;}bool GCppParser::ParseTypeDef(){	Advance(); // move past the "typedef" token	// Parse the type	const char* szTypeName = NULL;	GCppToken* pTok = GetToken(0);	GCppType* pType;	if(pTok->Equals("struct"))		pType = ParseStruct2(false, true);	else if(pTok->Equals("class"))		pType = ParseStruct2(true, true);	else if(pTok->Equals("enum"))		pType = ParseEnum(true);	else if(pTok->Equals("union"))		pType = ParseUnion2(true);	else if(GetToken(1)->Equals("("))		pType = ParseFunctionPointer(&szTypeName);	else		pType = ParseTypeRef(false, true);	if(!pType)		return false;	// Add the type to the current scope	pTok = GetToken(0);	while(true)	{		// Ignore any modifiers		ParseSuffixModifiers(false);		// todo: consume the modifiers		// Make the new type		pTok = GetToken(0);		if(szTypeName == NULL)		{			szTypeName = m_pStringHeap->Add(pTok->GetValue(), pTok->GetLength());			Advance();			pTok = GetToken(0);		}		GetCurrentScope()->m_pTypes->Add(szTypeName, pType);		szTypeName = NULL;		// hack for winnt.h		if(pTok->Equals("["))		{			Advance();			Advance();			Advance();			pTok = GetToken(0);		}		// See if there's another identifier for this type		if(!pTok->Equals(","))			break;		Advance(); // Move past the ","	}	return true;}GCppMethod* GCppParser::GetVarReferencedMethod(GCppType* pType){	while(true)	{		GCppToken* pTok = GetToken(0);		if(pTok->Equals(".") || pTok->Equals("->"))			Advance();		else			break;		pTok = GetToken(0);		GCppMethod* pTargetMethod = FindMethod(pTok->GetValue(), pTok->GetLength(), pType);		if(pTargetMethod)			return pTargetMethod;		GCppVariable* pVar = FindVariable(pTok->GetValue(), pTok->GetLength(), pType);		if(!pVar)			break;		pType = pVar->GetType();		Advance(); // Move past the var name	}	return NULL;}bool GCppParser::ParseMethodBody(GCppMethod* pMethod){	Advance(); // move past the "{" token	int nLevel = 1;	bool bLineStart = true;	while(nLevel > 0)	{		GCppToken* pTok = GetToken(0);		if(pTok->GetLength() == 0)			return OnError(pTok, "Unexpected end of file");		if(pTok->Equals("{"))		{			nLevel++;			bLineStart = true;		}		else if(pTok->Equals("}"))		{			nLevel--;			bLineStart = true;		}		else		{			// See if it's a local variable declaration			if(bLineStart)			{				GCppType* pType = FindType(pTok->GetValue(), pTok->GetLength());				if(pType)				{					Advance(); // Move past the type					while(true)					{						ParseSuffixModifiers(false);						pTok = GetToken(0);						if(pTok->GetLength() <= 0 || pTok->m_pFile->m_pFile[pTok->m_nStart] < 'A' || pTok->m_pFile->m_pFile[pTok->m_nStart] > 'z')							break;						// Make the local variable						char* szName = m_pStringHeap->Add(pTok->GetValue(), pTok->GetLength());						GCppVariable* pNewVar = new GCppVariable(pType, szName, GetCurrentScope()->m_eCurrentAccess, (GCppVarModifier)m_eVarModifiers);						m_eVarModifiers = 0;						GCppFile* pFile = GetCurrentFile();						if(pFile->IsProjectFile())							pNewVar->SetDeclaredInProjectFile();						pNewVar->SetSource(pFile->GetFilename(), pFile->GetCurrentLine());						if(!pMethod->m_pLocals)							pMethod->m_pLocals = new GConstStringHashTable(7, true);						pMethod->m_pLocals->Add(szName, pNewVar);						// See if there's more variables in a comma-list						Advance();						pTok = GetToken(0);						if(pTok->Equals(","))							Advance();						else							break;					}					m_eVarModifiers = 0;				}							}			// Look for direct method reference			GCppMethod* pTargetMethod = FindMethod(pTok->GetValue(), pTok->GetLength());						// Look for variable-referenced method			if(!pTargetMethod)			{				GCppVariable* pVar = FindVariable(pTok->GetValue(), pTok->GetLength(), pMethod);				if(pVar)				{					Advance(); // move past the var name					pTargetMethod = GetVarReferencedMethod(pVar->GetType());				}			}			// Look for type-referenced method			if(!pTargetMethod)			{				GCppType* pType = FindType(pTok->GetValue(), pTok->GetLength());				if(pType)				{					Advance();					pTok = GetToken(0);					if(pTok->Equals(":"))					{						Advance();						pTok = GetToken(0);						if(pTok->Equals(":"))						{							Advance();							pTok = GetToken(0);							pTargetMethod = FindMethod(pTok->GetValue(), pTok->GetLength(), pType);						}					}				}			}			// Consume the method call(s)			if(pTargetMethod)			{				while(true)				{					// Add the call					if(!pMethod->m_pCalls)						pMethod->m_pCalls = new GPointerArray(16);					pMethod->m_pCalls->AddPointer(pTargetMethod);					// Check for method calls on the return type					Advance(); // Move past the method name					pTok = GetToken(0);					if(pTok->Equals("("))					{						// Move past the parameters						int nLevel = 1;						while(nLevel > 0)						{							Advance();							pTok = GetToken(0);							if(pTok->GetLength() <= 0 ||								pTok->Equals("{") ||								pTok->Equals("}"))								return OnError(pTok, "Expected a ')'");							if(pTok->Equals("("))								nLevel++;							else if(pTok->Equals(")"))								nLevel--;						}						Advance();						pTok = GetToken(0);						// Check for another call						pTargetMethod = GetVarReferencedMethod(pTargetMethod->GetType());						if(!pTargetMethod)							break;					}				}			}			bLineStart = false;			if(pTok->Equals(";"))				bLineStart = true;		}		Advance();	}	return true;}bool MacroCompare(const char* szBody, const char* szParam, int* nSize){	*nSize = 0;	while(true)	{		if(*szParam <= ' ' || *szParam == ',' || *szParam == ')')			break;		if(*szBody != *szParam)			return false;		szBody++;		szParam++;		(*nSize)++;	}	if((*szBody >= 'A' && *szBody <= 'Z') ||		(*szBody >= 'a' && *szBody <= 'z') ||		(*szBody >= '0' && *szBody <= '9') ||		*szBody == '_')		return false;	return true;}#define MAX_MACRO_PARAMS 25bool GCppParser::ParseMacro(const char* szDef){	// Parse the macro definition params	int nDefPos = 0;	int nParamCount = 0;	const char* pParamDefs[MAX_MACRO_PARAMS];	if(szDef && szDef[nDefPos] == '(')	{		bool bNewParam = true;		while(true)		{			nDefPos++;			if(szDef[nDefPos] == ')' || szDef[nDefPos] == '\0')				break;			if(bNewParam && szDef[nDefPos] > ' ')			{				pParamDefs[nParamCount++] = &szDef[nDefPos];				bNewParam = false;			}			else if(szDef[nDefPos] == ',')				bNewParam = true;						if(nParamCount >= MAX_MACRO_PARAMS)				break;		}		if(szDef[nDefPos] == ')')			nDefPos++;	}	// Parse the macro implementation params	GAssert(m_nActiveTokens > 0, "expected a macro token");	m_nActiveTokens--; // undo the macro name token	if(!szDef)		return true;		const char* pParamImpls[MAX_MACRO_PARAMS];	if(nParamCount > 0)	{		GetNextToken(); // Read the next token		GCppToken* pTok = GetToken(m_nActiveTokens - 1);		if(!pTok->Equals("("))			return OnError(pTok, "Expected a '('");		m_nActiveTokens--; // undo the "(" token		int nImplParams = 0;		GetNextToken();		pTok = GetToken(m_nActiveTokens - 1);		while(true)		{			if(pTok->Equals(")"))				break;			if(nImplParams >= MAX_MACRO_PARAMS)				break;			pParamImpls[nImplParams++] = pTok->GetValue();			m_nActiveTokens--; // undo the token			GetNextToken();			pTok = GetToken(m_nActiveTokens - 1);			if(pTok->Equals(")"))				break;			if(!pTok->Equals(","))				return OnError(pTok, "Expected a ',' or ')'");			m_nActiveTokens--; // undo the ',' token			GetNextToken();			pTok = GetToken(m_nActiveTokens - 1);		}		if(nImplParams < nParamCount)			return OnError(pTok, "Not enough macro parameters");		m_nActiveTokens--; // undo the ')' token	}	// Make an implementation of the macro (in two passes)	char* szBuf = NULL;	int nBufPos;	int nPass;	for(nPass = 0; nPass < 2; nPass++)	{		nBufPos = 0;		const char* szDefBody = &szDef[nDefPos];		bool bTokenStart = true;		int nParamSize = 0;		while(*szDefBody != '\0')		{			if(*szDefBody == '#')			{				szDefBody++;				continue;			}			// See if we've got a parameter			const char* szParam = NULL;			if(bTokenStart && *szDefBody >= 'A')			{				bTokenStart = false;				int i;				for(i = 0; i < nParamCount; i++)				{					if(MacroCompare(szDefBody, pParamDefs[i], &nParamSize))					{						szParam = pParamImpls[i];						break;					}				}			}			// See if we're on a token delimeter			if(*szDefBody < 'A' || *szDefBody > 'z' || (*szDefBody > 'Z' && *szDefBody < 'a' && *szDefBody != '_'))				bTokenStart = true;			// Update the buffer			if(szParam)			{				// Do the parameter replacement				szDefBody += nParamSize;				while(true)				{					if(*szParam <= ' ' || *szParam == ',' || *szParam == ')')						break;					if(nPass > 0)						szBuf[nBufPos] = *szParam;					nBufPos++;					szParam++;				}			}			else			{				if(nPass > 0)					szBuf[nBufPos] = *szDefBody;				nBufPos++;				szDefBody++;			}		}		if(nPass == 0)			szBuf = new char[nBufPos + 10];		else			szBuf[nBufPos] = '\0';	}	// Parse the buffer like a #include file	char szOldDir[256];	getcwd(szOldDir, 256);	bool bProjectFile = GetCurrentFile()->IsProjectFile();	PushBuffer(szBuf, szOldDir, bProjectFile, GetCurrentFile()->GetFilename());	return true;}

⌨️ 快捷键说明

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