📄 macro.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 + -