📄 type.cpp
字号:
// Class.cpp: implementation of the CType class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Type.h"
#include "Enum.h"
#include "Identifiers.h"
#include "Symbols.h"
#include "CPGlobals.h"
#include "Xml.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
BEGIN_TEST_DUMP(CType)
TEST_DUMP_BASE(CIdentifier)
TEST_DUMP(mBaseClassList)
END_TEST_DUMP()
CType::CType(CPage* ipPage/*=NULL*/, int iLine/*=1*/, int iColumn/*=1*/)
:
CIdentifier(ipPage, iLine, iColumn)
{
mAccessTrim = TRIM_PRIVATE;
mType = TYPE_CLASS;
}
CType::~CType()
{
POSITION pos = NULL;
pos = mBaseClassList.GetHeadPosition();
while(pos != NULL)
delete mBaseClassList.GetNext(pos);
}
BOOL CType::ParseDeclare(CTokenList& ioList, POSITION& ioPos)
{
CToken* pToken = NULL;
NEXT_TOKEN_OR_RETURN_VALUE(FALSE);
//类型名
if(pToken->GetType() == TT_WORD)
{
mName = pToken->GetContent();
NEXT_TOKEN_OR_RETURN_VALUE(FALSE);
}
else //未命名
{
mName.Format("vuxtype_%d", gIndex++);
}
if(pToken->GetType() == TT_SEMICOLON) // class CMyClass;
{
return FALSE;
}
else if(pToken->GetType() == TT_LSQUARE) // class CMyClass {
{
return TRUE;
}
else if(pToken->GetType() == TT_COLON) //class CMyClass :
{
//基类列表
while(TRUE)
{
NEXT_TOKEN_OR_RETURN_VALUE(FALSE);
CIdenItem* pIdenItem = gIdens.Search(pToken->GetContent());
if( pIdenItem!= NULL && pIdenItem->IsAccessTrim())
continue;
if(pToken->GetType() != TT_WORD)
TOKEN_EXCEPTION();
//在析构函数中删除
CString* pBaseName = new CString(pToken->GetContent());
mBaseClassList.AddTail(pBaseName);
//抛弃模板参数
if(ioPos != NULL)
{
pToken = ioList.GetAt(ioPos);
ASSERT(pToken != NULL);
if(pToken->GetType() == TT_LT) // <
{
while(TRUE)
{
NEXT_TOKEN_OR_RETURN_VALUE(FALSE);
if(pToken->GetType() == TT_GT) // >
break;
}
}
}
NEXT_TOKEN_OR_RETURN_VALUE(FALSE);
if(pToken->GetType() == TT_LSQUARE) // {
break;
else if(pToken->GetType() != TT_COMMA) // 不是{,就只能是,
TOKEN_EXCEPTION();
}
}
else
{
TOKEN_EXCEPTION();
}
//TEST_TRACE(mBaseClassList);
return TRUE;
}
void CType::ParseBody(CTokenList& ioList, POSITION& ioPos)
{
ASSERT(ioPos != NULL);
CToken* pToken = NULL;
while(ioPos != NULL)
{
POSITION currPos = ioPos;
NEXT_TOKEN_OR_RETURN();
//类结尾
if(pToken->GetType() == TT_RSQUARE)
{
if(ioPos != NULL)
{
pToken = ioList.GetAt(ioPos);
if(pToken->IsType(TT_SEMICOLON))
ioList.GetNext(ioPos);
}
break;
}
CIdenItem* pIden = gIdens.Search(pToken->GetContent());
KEYWORD key = KEY_NOT;
if(pIden != NULL) key = pIden->keyIndex;
switch(key)
{
//访问修饰符
case KEY_PRIVATE:
mAccessTrim = TRIM_PRIVATE;
NEXT_TOKEN_OR_RETURN();
break;
case KEY_PROTECTED:
mAccessTrim = TRIM_PROTECTED;
NEXT_TOKEN_OR_RETURN();
break;
case KEY_PUBLIC:
mAccessTrim = TRIM_PUBLIC;
NEXT_TOKEN_OR_RETURN();
break;
//类内的枚举
case KEY_ENUM:
ParseEnum(ioList, ioPos);
break;
//嵌套类型
case KEY_STRUCT:
ParseType(ioList, ioPos, TYPE_STRUCT, TRIM_PUBLIC);
break;
case KEY_UNION:
ParseType(ioList, ioPos, TYPE_UNION, TRIM_PUBLIC);
break;
case KEY_CLASS:
ParseType(ioList, ioPos, TYPE_CLASS, TRIM_PRIVATE);
break;
case KEY_INTERFACE:
ParseType(ioList, ioPos, TYPE_INTERFACE, TRIM_PRIVATE);
break;
//其他不能根据开头关键字判别内容的代码
default:
ioPos = currPos; //从刚读到的token开始解析,而不是从关键字后开始解析
ParseMember(ioList, ioPos);
break;
}
}
}
CEnum* CType::ParseEnum(CTokenList& ioList, POSITION& ioPos)
{
ASSERT(ioPos != NULL);
CToken* pToken = ioList.GetAt(ioPos);
CEnum* pEnum = CEnum::ParseEnum(ioList, ioPos);
pEnum->SetCurrScope(gScope.GetCurrScope());
//将枚举名作为常量标识符进行保存
CString scope = gScope.GetCurrScope();
CString name;
while(pEnum->GetNextItem(name))
{
gIdens.AddIdentifier(scope + name, ID_CONST);
}
//命名枚举作为一个数据类型,保存到符号
CString fullName;
pEnum->GetFullName(fullName);
gIdens.AddIdentifier(fullName, ID_ENUM, pEnum);
return pEnum;
}
CType* CType::ParseType(CTokenList& ioList,
POSITION& ioPos,
UINT iType,
UINT iAccess/*=KEY_PRIVATE*/)
{
ASSERT(ioPos != NULL);
CToken* pToken = ioList.GetAt(ioPos);
//对于类定义,加入Idens并由其删除
CType* pClass = new CType(gpCurrPage,
pToken->GetLine(), pToken->GetColumn());
if(!pClass->ParseDeclare(ioList, ioPos))
{
delete pClass;
return NULL;
}
if(gpCurrPage != NULL)
{
CString comment;
gpCurrPage->GetComment(comment, pToken->GetLine());
pClass->SetComment(comment);
}
pClass->SetType(iType);
pClass->SetCurrScope(gScope.GetCurrScope());
//现在进入该类所在的域了
gScope.EnterScope(pClass->GetName());
pClass->ParseBody(ioList, ioPos);
//解析完成后,退出该类域
gScope.ExitScope();
CString fullName;
pClass->GetFullName(fullName);
if(gIdens.AddIdentifier(fullName, ID_TYPE, pClass, NULL))
{
gSymbols.AddType(pClass);
}
TEST_TRACE(pClass);
return pClass;
}
void CType::ParseMember(CTokenList& ioList, POSITION& ioPos)
{
CTokenList list;
BOOL definition = FALSE;
UINT symType;
if(CIdentifier::BeforeParseUnknowCode(ioList, ioPos, list, symType, definition))
{
if(symType == SYM_VARIABLE)
{
CVariableList varList;
CVariable::ParseVariable(list, mAccessTrim, varList);
POSITION pos = varList.GetHeadPosition();
while(pos != NULL)
{
CVariable* pVar = varList.GetNext(pos);
CString fullName;
pVar->GetFullName(fullName);
if(gIdens.AddIdentifier(fullName, ID_VARIABLE, pVar, NULL))
mVariableList.AddTail(pVar);
}
}
else if(symType == SYM_FUNCTION)
{
CExFunction* pFunc;
if(!definition)
pFunc = CExFunction::ParseFunction(list, mAccessTrim,
definition, NULL, NULL, TRUE);
else
pFunc = CExFunction::ParseFunction(list, mAccessTrim, definition,
&ioList, &ioPos, TRUE);
TEST_TRACE(pFunc);
CString fullName;
pFunc->GetFullName(fullName);
if(gIdens.AddIdentifier(fullName, ID_FUNCTION, pFunc, NULL))
mFunctionList.AddTail(pFunc);
}
else
{
ASSERT(FALSE);
}
}
}
void CType::ParseTypedef(CTokenList& ioList, POSITION& ioPos)
{
ASSERT(!ioList.IsEmpty() && ioPos != NULL);
CToken* pToken = ioList.GetAt(ioPos);
ASSERT(pToken != NULL);
//typedef后是否定义了一个数据类型,如是,则要首先解析
CIdentifier* pId = NULL;
CIdenItem* pIdenItem = gIdens.Search(pToken->GetContent());
if(pIdenItem != NULL)
{
switch(pIdenItem->keyIndex)
{
//枚举
case KEY_ENUM:
ioList.GetNext(ioPos); //跳过关键字
CType::ParseEnum(ioList, ioPos);
break;
//自定义数据类型
case KEY_STRUCT:
ioList.GetNext(ioPos); //跳过关键字
CType::ParseType(ioList, ioPos, TYPE_STRUCT, TRIM_PUBLIC);
break;
case KEY_UNION:
ioList.GetNext(ioPos); //跳过关键字
CType::ParseType(ioList, ioPos, TYPE_UNION, TRIM_PUBLIC);
break;
case KEY_CLASS:
ioList.GetNext(ioPos); //跳过关键字
CType::ParseType(ioList, ioPos, TYPE_CLASS, TRIM_PRIVATE);
break;
case KEY_INTERFACE:
ioList.GetNext(ioPos); //跳过关键字
CType::ParseType(ioList, ioPos, TYPE_INTERFACE, TRIM_PRIVATE);
break;
default:
break;
}
}
//读取内容
CTokenList list;
int paran = 0;
while(ioPos != NULL)
{
CToken* pToken = ioList.GetNext(ioPos);
ASSERT(pToken != NULL);
if(pToken->IsLParan()) paran++;
else if(pToken->IsRParan()) paran--;
if(pToken->GetType() == TT_SEMICOLON && paran==0)
break;
list.AddTail(pToken);
}
POSITION pos = list.GetTailPosition();
paran = 0;
while(pos != NULL)
{
CToken* pToken = list.GetPrev(pos);
//对于函数指针,跳过参数表
if(pToken->IsLParan()) paran++;
else if(pToken->IsRParan()) paran--;
if(paran != 0)
{
while(pos != NULL)
{
pToken = list.GetPrev(pos);
if(paran == 0) break;
if(pToken->IsLParan()) paran++;
else if(pToken->IsRParan()) paran--;
}
}
if(pToken->GetType() == TT_WORD)
{
TEST_TRACE(pToken->GetContent());
while(pos != NULL)
{
pToken = list.GetPrev(pos);
if(pToken->GetType() == TT_TIMES || pToken->GetType() == TT_BIT_AND)
{
continue;
}
else if(pToken->GetType() == TT_COMMA && pos != NULL)
{
pToken = list.GetPrev(pos);
TEST_TRACE(pToken->GetContent());
}
else
{
return;
}
}
}
}
}
void CType::OutputSymbols(LPCTSTR iDocDir)
{
CString fullName;
GetFullName(fullName);
CXml xml(30);
CString path, tag;
path.Format("<class name=\"%s\">", fullName);
xml.AddNode(path, NULL, NULL, "</class>");
xml.AddNode("<explain>", path, mComment, "</explain>");
POSITION pos = mFunctionList.GetHeadPosition();
while(pos != NULL)
{
CExFunction* pFun = mFunctionList.GetNext(pos);
pFun->OutputSymbols(xml, path);
}
/*
pos = mVariableList.GetHeadPosition();
while(pos != NULL)
{
CVariable* pVar = mVariableList.GetNext(pos);
CString type;
pVar->GetType(type);
CString fullName;
pVar->GetFullName(fullName);
}
*/
CString dir(iDocDir);
xml.Save(dir + mName + ".xml");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -