脚本宝典收集整理的这篇文章主要介绍了【lua源码分析】lctype的作用及原理,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
在看lua词法分析部分的时候,看到lislalpha
这个宏的定义,,从名字的上的意思是“判断是否是字母”。
在lctyPE.h文件中还定义了其它的宏(用作判断):
#define ALPHABIT 0
#define DIGITBIT 1
#define PRINTBIT 2
#define SPACEBIT 3
#define XDIGITBIT 4
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
上面的testprop中的luai_ctype_定义在lctype.cpp下:
LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
0x00, /* EOZ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */
0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
以lislalpha为例,传入一个char值,MASK偏移0位,也就还是1,然后通过testprop计算值,在testprop中,从luai_ctype_数组中获取的一个值与MASK相与(&),然后得到一个值,c语言中,非0取即为真。
那什么时候为0,什么时候非0呢。其实在luai_ctype_数组中,总共存在7种值,分别是:
- 0x04 对应的二进制为 00000100
- 0x16 对应的二进制为 00010110
- 0x15 对应的二进制为 00010101
- 0x05 对应的二进制为 00000101
- 0x08 对应的二进制为 00001000
- 0x0c 对应的二进制为 00001100
- 0x00 对应的二进制为 00000000
lislalpha宏中,总是与1相与(&),1的二进制为00000001,根据相与的结果,如果要使lislalpha返回非0(即为true)则,对应的数(二进制表示)末尾必须为1,以上满足lislalpha返回非0的值只有0x05,0x15,0x05,0x15的二进制表示,末尾为1。再统计,0x05,0x15所在luai_ctype_数组中的序列分别为:
**luai_ctype_数组序列**
66 - 71 数值为:0x15
72 - 91 数值为:0x05
98 - 103 数值为:0x15
104 - 123 数值为:0x05
对照ASCII码表,因为计算时,索引加1,对就的ASCII码就要减1
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
所以以上的数组序列,分别对应ASCII码中的大写字母和小字字母。同理可得到:
//**判断是否是字母或数字**
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
//**判断是否是数字**
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
//**判断是否是空格**
#define lisspace(c) testprop(c, MASK(SPACEBIT))
//**判断是否是可打印字符**
#define lisprint(c) testprop(c, MASK(PRINTBIT))
//**判断是否是数字或字母(大写A到G,小写a到g)(不知道为什么要这样?)**
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
以上是脚本宝典为你收集整理的【lua源码分析】lctype的作用及原理全部内容,希望文章能够帮你解决【lua源码分析】lctype的作用及原理所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。