📄 token.h
字号:
#ifndef __TOKEN_H__
#define __TOKEN_H__
#pragma once
//记号类别
enum {
TT_UNDEFINED, //未定义
TT_EOL, // '\n'
TT_REVERSE, // '\\'转义符
TT_PREPROCESSOR, //预编译 #
TT_CONNECT_LINE, //连行符 \\\n
TT_CONNECT, //宏语法中的连接符 ##
TT_SINCOMMENT, //单行注释 //
TT_MULCOMMENT, //多行注释 /*
TT_LITERAL_BEGIN, //后面的是文字常量
TT_WSTRING, //宽字符串 L"
TT_WCHAR, //宽字符 L'
TT_DIGIT, //数字 0-9
TT_STRING, //字符串 "
TT_CHAR, //字符 '
TT_IDENTIFIER_BEGIN, //后面是标识符
TT_WORD, //单词 a-z, A-Z, _
TT_OPERATOR_BEGIN, //后面的是操作符
//括号
//单字节
TT_LPARAN, //小括号左 (
TT_RPARAN, //小括号右 )
TT_LBRACE, //中括号左 [
TT_RBRACE, //中括号右 ]
TT_LSQUARE, //大括号左 {
TT_RSQUARE, //大括号右 }
//特殊操作符
//单字节
TT_COMMA, //逗号 ,
TT_SEMICOLON, //分号 ;
TT_COLON, //冒号 :
TT_SELECT, //选择 ?
//双字节
TT_SCOPE, //域符号 ::
//操作符开始
//单字节
TT_PLUS, // +
TT_MINUS, // -
TT_TIMES, // *
TT_DIV, // /
TT_MOD, // %
TT_XOR, // ^
TT_BIT_AND, // &
TT_BIT_OR, // |
TT_BIT_NOT, // ~
TT_LOGIC_NOT, // !
TT_ASSIGN, // =
TT_LT, // <
TT_GT, // >
//双字节
TT_NGT, // <=
TT_NLT, // >=
TT_PLUS_PLUS, // ++
TT_MINUS_MINUS, // --
TT_LMB, // <<
TT_RMB, // >>
TT_EQ, // ==
TT_NEQ, // !=
TT_AND, // &&
TT_OR, // ||
TT_PLUS_ASSIGN, // +=
TT_MINUS_ASSIGN, // -=
TT_DIV_ASSIGN, // /=
TT_MOD_ASSIGN, // %=
TT_XOR_ASSIGN, // ^=
TT_BIT_AND_ASSIGN, // &=
TT_BIT_OR_ASSIGN, // |=
TT_TIMES_ASSIGN, // *=
TT_ARROW, // ->
TT_DOT, // .
TT_DOT_STAR, // .*
//TT_SELECT, // ?:
//三字节
TT_LMB_ASSIGN, // <<=
TT_RMB_ASSIGN, // >>=
TT_ARROW_STAR, // ->*
//
//new
//new[]
//delete
//delete[]
TT_COUNT, //token类别数量
};
//子类别
//采用宏定义方式,便以处理有/无符号数之间的关系,如TTS_CHAR+1 == TTS_UNSIGNED_CHAR
#define TTS_NON 0
#define TTS_CHAR 1
#define TTS_UNSIGNED_CHAR 2
#define TTS_SHORT 3
#define TTS_UNSIGNED_SHORT 4
#define TTS_INT 5
#define TTS_UNSIGNED_INT 6
#define TTS_LONG 7
#define TTS_UNSIGNED_LONG 8
#define TTS_FLOAT 9
#define TTS_DOUBLE 10
#define NEXT_TOKEN_OR_BREAK() \
if(ioPos == NULL) break; \
pToken = pToken = ioList.GetNext(ioPos); \
if(pToken == NULL) break;
#define CURR_TOKEN_OR_BREAK() \
if(ioPos == NULL) break; \
pToken = pToken = ioList.GetAt(ioPos); \
if(pToken == NULL) break;
#define NEXT_TOKEN_OR_RETURN() \
if(ioPos == NULL) return; \
pToken = pToken = ioList.GetNext(ioPos); \
if(pToken == NULL) return;
#define NEXT_TOKEN_OR_RETURN_VALUE(value) \
if(ioPos == NULL) return value; \
pToken = pToken = ioList.GetNext(ioPos); \
if(pToken == NULL) return value;
//记号对象。
//使用CTokenReader::ReadTokenList()将源代码转换为记号对象序列,以便进行下一步解析。
class CToken
{
public:
//构造函数
CToken(int iLine, int iColumn, UINT iType=TT_UNDEFINED, BOOL iForeSpace=0);
CToken(int iLine, int iColumn, CToken* ipOther);
CToken(CToken* ipOther);
//析构函数
virtual ~CToken();
//读取一个单词
int ReadWord(LPCTSTR iopCode);
//读取一个数字
int ReadDigit(LPCTSTR ipCode);
//读取单行注释
int ReadSingleLineComment(LPCTSTR ipCode);
//读取多行注释
int ReadMulLineComment(LPCTSTR ipCode);
//读取字符串
int ReadString(LPCTSTR ipCode);
//读取宽字符串
int ReadWString(LPCTSTR ipCode);
//读取字符
int ReadChar(LPCTSTR ipCode);
//读取宽字符
int ReadWChar(LPCTSTR ipCode);
//拷同内容字符串到记号对象
void CopyContent(LPCTSTR ipCode, int iLen);
void CopyContent(LPCTSTR ipCode, int iLen, LPCTSTR iHead);
//更新内容字符串
void UpdateContent(LPCTSTR iNewContent);
//在内容字符串后面连接一个字符串
void CatContent(LPCTSTR iCat);
//将注释整理后输出
void CleanupComment(CString& oComment);
private:
//判断一个字符是否可作为一个单词的开头
BOOL IsBeginOfWord(char ch);
//判断一个字符是否可作为一个单词的一部分
BOOL IsWordPart(char ch);
//判断一个字符是否可作为一个数字的开头
BOOL IsDigit(char ch);
public:
//取得记号的内容字符串
LPCTSTR GetContent() const {return mpContent;};
//取得记号的类型
UINT GetType() const {return mType;};
//判断记号是否属于某种类型
BOOL IsType(UINT iType) const {return mType == iType;};
//取得记号的子类型,用于数字类
UINT GetSubType() const {return mSubType;};
//设置记号类型
void SetType(UINT iType) {mType = iType;};
//取得记号的行号
int GetLine() const {return mLine;};
//取得记号的列号
int GetColumn() const {return mColumn;};
//设置记号的行号
void SetLine(int iLine) {mLine=iLine;};
//设置记号的列号
void SetColumn(int iColumn) {mColumn=iColumn;};
//判断记号是否前面有空格
BOOL IsForeSpace() const {return mForeSpace>0;};
//设置记号的空格数
void SetForeSpace(UINT iForeSpace) {mForeSpace=iForeSpace;};
//将记号的内容字符串边接到一个字符串后面
void CatContentTo(CString& oDes) {if(mForeSpace>0) oDes+=' '; oDes += mpContent;};
//取得操作符记号的优先级
int GetPrecedence() const {ASSERT(mType>=0 && mType<TT_COUNT); return CToken::sPrecedence[mType];};
//判断是否正式记号,在经过预处理后应该只保存正式记号
BOOL IsFormalToken() const {return mType>TT_LITERAL_BEGIN;};
static BOOL IsFormalToken(UINT iType) {return iType>TT_LITERAL_BEGIN;};
//判断记号是否是操作符
BOOL IsOperator() const {return mType > TT_OPERATOR_BEGIN;};
//判断记号是否前面是文字常量
BOOL IsLiteral() const { return mType > TT_LITERAL_BEGIN && mType < TT_IDENTIFIER_BEGIN;};
//判断记号是否前面是标识符
BOOL IsIdentifier() const { return mType == TT_WORD;};
//判断记号是否前面是左括号中的一种,包括< ( [ {
BOOL IsLParan() const {return mType==TT_LPARAN || mType==TT_LBRACE || mType==TT_LSQUARE;};
//判断记号是否前面是右括号中的一种,包括> ) ] }
BOOL IsRParan() const {return mType==TT_RPARAN || mType==TT_RBRACE || mType==TT_RSQUARE;};
protected:
int mLine; //行号
int mColumn; //列号
char* mpContent; //代码内容
UINT mType; //token类别
UINT mSubType; //部分token的字类别,如数字可分为int, double等
UINT mForeSpace; //前面是否有空格
public:
static int sPrecedence[TT_COUNT]; //各操作符的优先级
UNIT_TEST(CToken)
};
DECLARE_TEST_DUMP(CToken)
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -