探秘lua词法分析

欢迎关注公众号《后台开发探索之旅》。

 

词法分析实例

在《递归下降算法》一节里,介绍过数学表达式的词法分析,现在正式开始lua语言的词法分析。

以一段简单的lua代码为例:

-- 输出最大值
local a, b = 10.5, 20.00
local c = math.max(a, b)
local d = string.format(
  "maxval(%f,%f)=%f", a, b, c)
print(d)

代码逻辑为取a和b的最大值,赋给c,再打印a、b、c的值。

 

词法分析结果:

local a , b = 10.50 , 20.00 
local c = math . max ( a , b 
) local d = string . format 
( maxval(%f,%f)=%f , a , 
b , c ) print ( d ) <eof>

 

可以看出,lua的词法分析是按照以下几种类型区分的:

  • 标识符:如 local、a、b、math

  • 标点符号:如 , = ( )

  • 数字:如10.5、20.00

  • 字符串:如 "maxval(%f,%f)=%f"

  • 注释:以--开头的为注释

 

 

词法分析逻辑

lua的词法分析模块将源码文件作为一个字符流读入,每次取出一个字符,根据字符值做不同的处理,用代码实现就是一个超大switch语句。下面逐一介绍各个字符的处理逻辑。

 

\r 或 \n

linux系统里换行符为"\n",Windows系统换行符为"\r\n",为保证lua代码在两种系统行数一致,将 "\r\n" 和 "\n\r" 作为一行。

 

减号 -

在lua里'-'有多种可能的意义,如负号、减号、注释、多行注释。

  • 若下个字符不为'-',表示负号或减号,如 -100, a-b

  • 若下个字符为'-',且下下个字符为'[',按照多行注释处理,如 --[[ 多行注释 ]]

  • 否则按照单行注释处理,如 -- 单行注释

 

左方括号 [

可能为多行字符串,也可能为table取key操作。

  • 若为"[[" 或 "[=[" 等格式,读取多行字符串,如 [[ string ]]

  • 否则,表示取key操作,如 a["data"]=1

 

等号 =

  • 若下个字符为'=',表示相等比较,如 a==b

  • 否则,表示赋值操作,如 a=1

 

< 或 > 或 ~

  • 若下个字符为'=',表示小于等于、大于等于、不等于,如 <= >= ~=

  • 否则表示小于、大于

 

" 或 '

  • 表示字符串开始,如 "abc" 或 'abcd'

 

点号 .

  • 若为"...",表示变长参数,如 print(fmt, ...)

  • 若为"..",表示字符串连接符,如 a .. b

  • 若为".123",表示浮点数 0.123

  • 若为"a.b",表示table成员引用,等价于a["b"]

 

-1

  • 文件结束符EOZ

 

空白字符

  • 如 ' ' '\t' 

 

数值

  • 如 123、2.2、32e+1、0.2e-2 

 

标识符

  • 以字母或下划线开头,后面为字母、数字、下划线,如 abc123, _data

 

单操作符

  • 如 + - * / % 

 

 

数据结构

typedef union {
  lua_Number r;
  TString *ts;
} SemInfo;

typedef struct Token {
  int token;
  SemInfo seminfo;
} Token;

Token结构体用来表示一个分词,token表示分词类型,seminfo存储分词值

分词类型token枚举数值存储举例
保留字TK_FOR for
保留字TK_ELSE else
数值TK_NUMBERseminfo.r123
标识符TK_NAMEseminfo.tsmyname
字符串TK_STRINGseminfo.ts"abc"

 

不同于常规的先做词法分析,再做语法分析的步骤,lua以语法分析为主,在需要的时候取出一个分词继续分析,所以取词函数luaX_next在许多地方被调用。

 

lua词法分析本身比较简单,核心逻辑在 llex.c 文件,代码量不足500行,感兴趣的可以看看。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值