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

📄 macro.cpp

📁 这是一个能够自动生成文档的程序
💻 CPP
字号:
// Macro.cpp: implementation of the CMacro class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Identifiers.h"
#include "CPGlobals.h"
#include "Macro.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

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

BEGIN_TEST_DUMP(CMacro)
    TEST_DUMP(mName)
	TEST_DUMP(mParamList)
    TEST_DUMP(mTokenList)
END_TEST_DUMP()


CMacro::CMacro(CPage* ipPage/*=NULL*/, int iLine/*=1*/, int iColumn/*=1*/)
:
CIdentifier(ipPage, iLine, iColumn)
{
    mDefined = TRUE;
}

CMacro::~CMacro()
{
	POSITION pos = NULL;
	
	pos = mParamList.GetHeadPosition();
	while(pos != NULL)
		delete mParamList.GetNext(pos);

	pos = mTokenList.GetHeadPosition();
	while(pos != NULL)
		delete mTokenList.GetNext(pos);
}

void CMacro::ParseContent(CTokenList& ioList, POSITION& ioPos)
{
	POSITION currPos = ioPos; //记录当前Token的Position, 以便从输入列表中删除该项

	CToken* pToken = NULL;
	NEXT_TOKEN_OR_RETURN();	
	 // ( 宏参数,(紧连宏名的才是参数,中间有空格的不是
	if(pToken->GetType() == TT_LPARAN  && !pToken->IsForeSpace())
	{
		ParseParam(ioList, ioPos);
        currPos = ioPos;
		NEXT_TOKEN_OR_RETURN();
	}

	//宏定义
	while(TRUE)
	{
		if(pToken->GetType() == TT_EOL)
			break;

		//加入mTokenList, 在析构函数中删除
		CToken* pNew = new CToken(pToken);
		AddToken(pNew);

        currPos = ioPos;
		NEXT_TOKEN_OR_BREAK();
	}

	TEST_TRACE(this);
}

void CMacro::ParseParam(CTokenList& ioList, POSITION& ioPos)
{
    CToken* pToken;
	CString param;
	while(TRUE)
	{
		POSITION currPos = ioPos;
		NEXT_TOKEN_OR_BREAK();
		//ioList.RemoveAt(currPos);
		switch(pToken->GetType())
		{
		case TT_COMMA: // ,
			AddParam(param);
			TEST_TRACE(param);
			param.Empty();
			break;
		case TT_SINCOMMENT: //注释
		case TT_MULCOMMENT: 
			goto WHILE_CONTINUE;
		case TT_RPARAN:    // )
			AddParam(param);
			TEST_TRACE(param);
			goto WHILE_BREAK;
		case TT_WORD:
			if(!param.IsEmpty())
				TOKEN_EXCEPTION();
			param += pToken->GetContent();
			break;
		default:
			TOKEN_EXCEPTION();
		}
WHILE_CONTINUE:
		continue;
WHILE_BREAK:
		break;
	}
}

BOOL CMacro::ParseArg(CTokenList& ioList, POSITION& ioPos, CTokenList& oArgTokenList)
{
	CToken* pToken = NULL;
	int paran = 0;
    while(ioPos != NULL)
	{
        POSITION currPos = ioPos;
		NEXT_TOKEN_OR_RETURN_VALUE(FALSE);
        UINT type = pToken->GetType();
        
		//是否出现不匹配的)
		if(type == TT_LPARAN) paran--;
		else if(type == TT_RPARAN) paran++;

		ioList.RemoveAt(currPos);

		if(paran == 1)    //结束
		{
			delete pToken; //删除 )
			return FALSE;
		}
		//出现,,返回TRUE,表示还有下一个实参
		//但位于()内的,除外
		else if(type == TT_COMMA && paran >= 0) 
		{
			delete pToken; //删除 ,
			return TRUE;
		}
        else
		{
			//if(oArgTokenList.IsEmpty())
			//	pToken->SetForeSpace(1);
			TEST_TRACE(pToken);
		    oArgTokenList.AddTail(pToken);
		}
	}

	return FALSE;
}

void CMacro::AddParam(LPCTSTR iParam) 
{ 
	if(iParam == NULL || strlen(iParam) == 0)
		return;

	CString* pParam = new CString(iParam); 
	mParamList.AddTail(pParam);
}


void CMacro::Unwind(CTokenList& ioList, POSITION& ioPos)
{
	ASSERT(!ioList.IsEmpty());
	ASSERT(ioPos != NULL);

	//宏引用所在的行号列号
	int line = 1;
	int column = 1;

    //删除宏名称所在的token
	POSITION tempPos = ioPos;
	ioList.GetPrev(tempPos);
	if(tempPos != NULL)
	{
	    CToken* pMacroToken = ioList.GetAt(tempPos);
		line = pMacroToken->GetLine();
		column = pMacroToken->GetColumn();
 	    delete pMacroToken;
	    ioList.RemoveAt(tempPos);
	}

	//将mTokenList拷贝一份
	CTokenList list;
	tempPos = mTokenList.GetHeadPosition();
	while(tempPos != NULL)
	{
		CToken* pSrc = mTokenList.GetNext(tempPos);
		//最终拷贝到ioList,由Unwind的调用者删除
		CToken* pDes = new CToken(line, column, pSrc);
		list.AddTail(pDes);
	}

	POSITION currPos = ioPos;
	CToken* pToken = NULL;
	NEXT_TOKEN_OR_RETURN();
	
	if(pToken->GetType() == TT_LPARAN) //带参数
	{
		//从列表删除 ( 项的指针
		ioList.RemoveAt(currPos);

		CList<CTokenList*, CTokenList*> argListList;
		while(TRUE)
		{
			CTokenList* pArgList = new CTokenList();
		    BOOL next = ParseArg(ioList, ioPos, *pArgList); //读取参数
			if(!pArgList->IsEmpty()) 
				argListList.AddTail(pArgList);
			else
				delete pArgList;
			if(!next)
			{   
				currPos = ioPos;
				break;
			}
		}

		//if(argListList.GetCount() != mParamList.GetCount())
		//	TOKEN_EXCEPTION();
		
		//从删除 ( 项
		delete pToken;
		pToken = NULL;

		//替换参数

		POSITION paramPos = mParamList.GetHeadPosition();
		POSITION argPos = argListList.GetHeadPosition();
		while(paramPos != NULL && argPos != NULL)
		{
			CString* pParam = mParamList.GetNext(paramPos);
			CTokenList* pArgList = argListList.GetNext(argPos);
			
			POSITION defPos = list.GetHeadPosition();
			CToken* pPreToken = NULL;
			POSITION prePos = NULL;
			POSITION currPos = NULL;
			pToken = NULL;
			while(defPos != NULL)
			{
				prePos = currPos;
				currPos = defPos;
				pPreToken = pToken;
				pToken = list.GetNext(defPos);
				ASSERT(pToken != NULL);

				if(pToken->GetContent() == *pParam)
				{				
					//# 将参数解析为字符串
					//并替换形参所在的token的内容为该字符串
					if(pPreToken != NULL && pPreToken->GetType() == TT_PREPROCESSOR) 
					{
						CString str;
						POSITION tempPos = pArgList->GetHeadPosition();
						CTokenReader::TokenListToCString(str, *pArgList, tempPos);
						
						//删除#
						delete pPreToken;
						list.RemoveAt(prePos);
						
						//将形参替换为实参
						pToken->UpdateContent(str);
						pToken->SetForeSpace(1);
						pToken->SetType(TT_STRING);
					}
					//前面没有#,删除形参,将实参直接插入列表
					else
					{
						//删除形参
						list.RemoveAt(currPos);
						int foreSpace = pToken->IsForeSpace();
						delete pToken;
						pToken = NULL;

						//将实参插入队列
						POSITION argPos = pArgList->GetHeadPosition();
						while(argPos != NULL)
						{
							CToken* pArgToken = pArgList->GetNext(argPos);
							CToken* pNew = new CToken(pArgToken);
							if(foreSpace > 0)
							    pNew->SetForeSpace(foreSpace);
							foreSpace = 0;
							if(defPos != NULL)
								list.InsertBefore(defPos, pNew);
							else
								list.AddTail(pNew);
						}
					}
				}
			}			
		}

		//删除实参
		tempPos = argListList.GetHeadPosition();
		while(tempPos != NULL)
		{
			//实参内容已拷贝到展开后的TokenList中了
			CTokenList* pArgList = argListList.GetNext(tempPos);
			POSITION inPos = pArgList->GetHeadPosition();
			while(inPos != NULL)
				delete pArgList->GetNext(inPos);
			delete pArgList;
		}
	}
	
	//处理连接符(无论是否带参数,都可以有连接符)
	CTokenReader reader;
	POSITION defPos = list.GetHeadPosition();
	CToken* pPreToken = NULL;
	POSITION prePos = NULL;
	POSITION tempCurrPos = NULL;
	CToken* pCurrToken = NULL;
	while(defPos != NULL)
	{
		pPreToken = pCurrToken;
		prePos = tempCurrPos;
		tempCurrPos = defPos;
	    pCurrToken = list.GetNext(defPos);
		ASSERT(pCurrToken != NULL);
		if(pCurrToken->GetType() == TT_CONNECT)
		{
			//删除##
			list.RemoveAt(tempCurrPos);
			delete pCurrToken;
			pCurrToken = NULL;
			
			if(pPreToken != NULL && defPos != NULL)
			{
				tempCurrPos = defPos;
				CToken* pNextToken = list.GetNext(defPos);
     
				//连接后的内容要重新分解为token
				CString content;
				pPreToken->CatContentTo(content);
				content += pNextToken->GetContent();
				CTokenList tempList;
				reader.ReadTokenList(tempList, content);
				POSITION newTempPos = tempList.GetHeadPosition();
				POSITION tempInsertPos = tempCurrPos;
				while(newTempPos != NULL)
				{
					CToken* pNewToken = tempList.GetNext(newTempPos);
					pNewToken->SetLine(pPreToken->GetLine());
					pNewToken->SetColumn(pPreToken->GetColumn());
                    pCurrToken = pNewToken;
					tempInsertPos = list.InsertAfter(tempInsertPos, pNewToken); //tempCurrPos != NULL
				}

				list.RemoveAt(prePos);
				delete pPreToken;
				pPreToken = NULL;

		        list.RemoveAt(tempCurrPos);
				delete pNextToken;
				pNextToken = NULL;

				tempCurrPos = tempInsertPos;
			}
		}
	}
	
	defPos = list.GetTailPosition();
	POSITION insertPos = currPos;
	while(defPos != NULL)
	{
		CToken* pDefToken = list.GetPrev(defPos);
		insertPos = ioList.InsertBefore(insertPos, pDefToken);
	}
	
	ioPos = insertPos;
	TEST_TRACE(ioList.GetAt(ioPos));
	TEST_TRACE(ioList);
}

void CMacro::ParseMacroFormCode(LPCTSTR iSrc)
{
	CTokenList list;
    CTokenReader reader;
	reader.ReadTokenList(list, iSrc);
	if(list.IsEmpty()) return;
    POSITION pos = list.GetHeadPosition();
	CToken* pToken = list.GetNext(pos);
	
	//由mIdens删除
	CMacro* pMacro = new CMacro(NULL);
	//宏名称
	pMacro->SetName(pToken->GetContent());
	pMacro->ParseContent(list, pos);
	gIdens.AddIdentifier(pMacro->GetName(), ID_MACRO, pMacro, NULL);

	reader.ClearTokenList(list);
}

⌨️ 快捷键说明

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