查看: 1337|回复: 0
打印 上一主题 下一主题

[其他] 提取lua代码的函数定义和调用信息

[复制链接]

9903

主题

126

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
53488
精华
316

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2019-11-30 16:39:52 |只看该作者 |倒序浏览

原链:https://blog.csdn.net/yudianxia/article/details/80008070

最近想做个工具来做一些lua代码检测,比如统计某函数体里的a函数的调用次数,调用绑定事件后是否有把其返回值在某退出函数里解绑定,或者某函数调用的参数是不是和协议文档里的有对应上(这个还是建议直接从协议文档生成lua代码的好).
大学时就用正则表达式做过java代码的解析了,这次想换个实现姿势,也想弄个通用点的,大致想法就是提取lua代码中的函数体和表达式信息,并转化成一些字符串列表方便查询。比如把一个函数调用拆成函数名、参数列表和返回值列表几个部分。还好lua是开源,干脆就从它的语法解析器下手,大部分工作它都做好了,我们只需要在某个时机把字符串保存下来。
为了方便查询、扩展结构和好看的打印,所以我用json格式存放解析后的信息。

表达式有好多类型,比如函数调用、赋值、判断语句等,暂时只需要用到函数调用的,以后有空再实现其它类型吧。

用法:

比如传入lua代码:
function func1()
local result_val = self:func2("arge")
end
将生成json代码:
{
  "func_name": "func1",
  "codes": [
  {
"type": "call_func",
"arges": [
"arge",
],
"rets": [
"result_val",
],
  "call_name": "call_func1",
  "call_full_name": "self:call_func1"
  }
  ],
}
func_name就是定义的函数名,codes是该函数体里的表达式列表。
为了简洁起见上面只是一部分json代码而已,因为lua支持嵌套的函数定义,如:
function func1()
local func2 = function (  )
self:call_func3()
end
end
所以每个函数体内又可以包含函数体,把整个lua文件当作一个函数(其实lua内部实现解析一个lua文件时也是把它当成一个闭包的),那上面代码的json结构大概就是:
{
"func_name": "outside",
"codes": [函数调用信息列表,最外层没调用函数所以这里为空],
"funcs": [
{
"func_name": "func1",
"codes": [func1函数体里没调用函数,所以这里也为空]
"funcs": [
{
"func_name": "func2",
"funcs": [终于没定义新函数了,所以这里为空],
"codes": [
{
"type": "call_func",
"arges": [],
"rets": [],
"call_name": "call_func3",
"call_full_name": "self:call_func3"
}

}
],
}

}
一个函数定义的信息有三字段:函数名(func_name),函数体里执行的表达式列表(codes),函数体里定义的函数列表(funcs)
表达式信息有五字段:类型(type),调用的函数名(call_name),调用的函数全名(call_full_name),参数列表(arges),返回值列表(rets)

具体项目代码见:https://github.com/liuhaopen/LuaMetaExtracter

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-12-2 16:35 , Processed in 0.087709 second(s), 28 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部