【lua源码分析】lctype的作用及原理

发布时间:2019-08-07 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【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,请注明来意。