Files
mir_server/sdk/srvlib/include/CustomLuaPreProcess.h

201 lines
9.0 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#pragma once
/****************************************************************
LUA脚本文本内容预处理器
LUA词法分析器不具有代码文本预处理的功能且在实际是用中需要用到代码包含等
C语言的预处理功能使
lua语法HTML中书写JavaScript代码的方式
使lua预处理器中预处理指令的语法规则如下
--#directive implemente data
1使--#include "FilePath"
使
1024
2使--#define NAME [VALUE]
--#undef NAME30
126
3使--#ifdef--#ifndef--#if MACRO == VALUE
--#if MACRO != VALUE--#else--#elif--#endif
****************************************************************/
class CCustomLuaPreProcessor :
protected wylib::stream::CMemoryStream
{
public:
typedef CMemoryStream Inherited;
/* 定义源文件行号信息 */
struct LineRange
{
TCHAR sFileName[MAX_PATH]; //源文件路径超过MAX_PATH则使用短文件名
INT_PTR nLineStart; //预处理后的起始行号
INT_PTR nLineEnd; //预处理后的结束行号
};
class CLineRangeList : public wylib::container::CBaseList<LineRange>
{
public:
/* 获取预处理后的行号对应的原始文件路径以及行号
* nLineNo 1
* nSrcLineNo 1
* @return nSrcLineNo为原始文件行号NULL
*/
LPCTSTR getSourceLineNumber(INT_PTR nLineNo, INT_PTR &nSrcLineNo);
};
public:
CCustomLuaPreProcessor();
~CCustomLuaPreProcessor();
/* 对输入脚本内容进行预处理
*sSourceText 0
*sFilePath
*cNewLine '\n'
*@return
*/
LPCTSTR parse(LPCTSTR sSourceText, LPCTSTR sFilePath, const TCHAR cNewLine = '\n');
//添加包含文件搜索目录
VOID addIncludeDirectory(LPCTSTR sPath)
{
m_IncludeDirList.add(new String(sPath));
}
//清空包含文件搜索目录
VOID clearIncludeDirectory();
/* 添加预处理宏定义
* sName
* sValue
*/
VOID addMacro(LPCTSTR sName, LPCTSTR sValue = NULL);
//移除一个宏定义
VOID removeMacro(LPCTSTR sName);
//清空预处理宏定义
VOID clearMacroList();
/* 获取源文件行号对照表
* pLineRange
* nCount
*@return pLineRange为空pLineRange中拷贝行信息数量
*/
INT_PTR getLineRangeData(LineRange *pLineRange, INT_PTR nCount);
/* 获取预处理后的行号对应的原始文件路径以及行号
* nLineNo 1
* nSrcLineNo 1
* @return nSrcLineNo为原始文件行号NULL
*/
LPCTSTR getSourceLineNumber(INT_PTR nLineNo, INT_PTR &nSrcLineNo);
protected:
/* 保留当前处理结果内并对新的输入脚本内容进行预处理
*sSourceText 0
*/
LPCTSTR ParseSource(LPCTSTR sSourceText);
//保存当前预处理器分析环境,将分析环境压入环境栈中
inline VOID SaveParseEnvir()
{
m_ParseEnvirStack.add(m_ParseEnvir);
}
//恢复上一个预处理器分析环境,恢复后将删除栈顶的分析环境对象
inline VOID RestorsParseEnvir()
{
m_ParseEnvir = m_ParseEnvirStack[m_ParseEnvirStack.count()-1];
m_ParseEnvirStack.trunc(m_ParseEnvirStack.count()-1);
}
//分析以“--#”文本开头的预处理行
VOID ProcessLine(LPCTSTR sLineText);
/* 处理并执行预处理指令的功能
*
*/
VOID ProcessDirective(LPCTSTR sDirective, LPCTSTR sData);
//对#include预处理指令功能的实现
VOID DirectiveOfInclude(LPCTSTR sData);
//对#define预处理指令的实现
VOID DirectiveOfDefine(LPCTSTR sData);
//对#undef预处理指令的实现
VOID DirectiveOfUndef(LPCTSTR sData);
//对#ifdef预处理指令的实现
VOID DirectiveOfIfdef(LPCTSTR sData);
//对#ifndef预处理指令的实现
VOID DirectiveOfIfndef(LPCTSTR sData);
//对#if预处理指令的实现
VOID DirectiveOfIf(LPCTSTR sData);
//对#else预处理指令的实现
VOID DirectiveOfElse(LPCTSTR sData);
//对#elif预处理指令的实现
VOID DirectiveOfElif(LPCTSTR sData);
//对#endif预处理指令的实现
VOID DirectiveOfEndif(LPCTSTR sData);
protected:
//预处理器词对象定义
typedef TCHAR PPToken[128];
/*** 语法分析副主函数集合 ***/
/*
* Comments: WhiteSpace分割词
* Param LPCTSTR sLinePtr:
* Param IN OUT LPCTSTR * sTokens:
* Param IN OUT INT_PTR & nTokenCount:
* @Return LPCTSTR: sLinePtr的位置便
*/
LPCTSTR delimiteLine(LPCTSTR sLinePtr, IN OUT PPToken *sTokens, IN OUT INT_PTR &nTokenCount);
//获取完全的预处理取词条件值
void refreshCondition();
//出现错误,标记终止分析
inline void abort(){ m_boErrorAbort = true; }
//情况已包含文件列表
void clearIncludedFileList();
protected:
//输出错误的函数
virtual VOID showError(LPCTSTR sError);
//带参数格式化的输出错误的函数
virtual VOID showErrorFormat(LPCTSTR sFmt, ...);
private:
/* 保留当前处理结果内并对新的输入脚本内容进行预处理
*
*sSourceText 0
*sFillFilePath
*/
LPCTSTR SaveFileDirAndParse(LPCTSTR sSourceText, LPCTSTR sFillFilePath);
//搜索并加载包含文件
bool SearchAndLoadIncludeFile(LPCTSTR sIncludeFileName, bool boEnableMultipleInclude);
//加载并分析包含文件
bool LoadIncludeFile(LPCTSTR sIncludeFilePath, bool boEnableMultipleInclude);
protected:
//预处理器分析环境
typedef struct tagPreProcParseEnvir
{
LPCTSTR sFilePath; //原始文件路径
LPCTSTR sParsePtr; //输入内容分析位置
LPCTSTR sNewLinePtr; //新行位置
LPCTSTR sLineEndPtr; //行尾位置
INT_PTR nLineNo; //当前分析的行号从1开始
}PREPROC_PARSERENVIR, *PPREPROC_PARSERENVIR;
//预处理器中的宏定义
typedef struct tagMacro
{
TCHAR sName[32];
TCHAR sValue[128];
}PREPROC_MACRO, *PPREPROC_MACRO;
PREPROC_PARSERENVIR m_ParseEnvir; //当前分析环境
wylib::container::CBaseList<PREPROC_PARSERENVIR> m_ParseEnvirStack; //预处理器代码分析环境列表,后进先出
wylib::container::CBaseList<String*> m_FilePathStack; //预处理器包含文件分析栈,后进先出
wylib::container::CBaseList<String*> m_IncludeDirList; //调用者预设的预处理包含文件搜索目录列表
wylib::container::CBaseList<PREPROC_MACRO> m_MacroList; //预定义宏列表
wylib::container::CBaseList<bool> m_ConditionList; //当前预处理条件表
wylib::container::CBaseList<LPTSTR> m_IncludedFileList; //预处理器已经包含过的文件列表
CLineRangeList m_LineRangeList; //源文件行号信息表
INT_PTR m_nLineNo; //当前总计文件行号
TCHAR m_NewLineChar; //新行符,默认是'\n'
bool m_boErrorAbort; //是否因错误而需要终止分析
bool m_boCurrCondition; //当前的预处理条件值
public:
//通过宏名称获取宏指针
const PPREPROC_MACRO getMacro(LPCTSTR sName);
};