首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Python搜索Lua文件中的所有函数调用

使用Python搜索Lua文件中的所有函数调用
EN

Stack Overflow用户
提问于 2021-10-11 23:17:35
回答 1查看 157关注 0票数 3

我想使用python搜索Lua文件中的所有函数调用。例如,我有一个Lua代码:

代码语言:javascript
运行
复制
function displayText (text)
    print(text)
end

sendGreetings = function(sender, reciever) 
    print("Hi " ..reciever.. " greetings from " ..sender.. "!")
end

displayText("Hello, World!")

sendGreetings("Roger", "Michael")

我希望python代码在该代码中搜索函数调用,并返回一个带有函数名称和参数的字典,因此输出应该如下所示:

代码语言:javascript
运行
复制
# {function_name: [param1, param2]}
{"displayText": ["Hello, World!"], "sendGreetings": ["Roger", "Michael"]}

我试图使用regex来实现它,但是我遇到了各种各样的问题,结果也不准确。而且,我不相信有一个用于Python的Lua解析器。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-11 23:47:33

可以使用luaparser (pip install luaparser)和递归遍历ast

代码语言:javascript
运行
复制
import luaparser
from luaparser import ast
class FunCalls:
   def __init__(self):
      self.f_defs, self.f_calls = [], []
   def lua_eval(self, tree):
      #attempts to produce a value for a function parameter. If value is a string or an integer, returns the corresponding Python object. If not, returns a string with the lua code
      if isinstance(tree, (luaparser.astnodes.Number, luaparser.astnodes.String)):
         return tree.n if hasattr(tree, 'n') else tree.s
      return ast.to_lua_source(tree)
   def walk(self, tree):
      to_walk = None
      if isinstance(tree, luaparser.astnodes.Function):
         self.f_defs.append((tree.name.id, [i.id for i in tree.args]))
         to_walk = tree.body
      elif isinstance(tree, luaparser.astnodes.Call):
         self.f_calls.append((tree.func.id, [self.lua_eval(i) for i in tree.args]))
      elif isinstance(tree, luaparser.astnodes.Assign):
         if isinstance(tree.values[0], luaparser.astnodes.AnonymousFunction):
            self.f_defs.append((tree.targets[0].id, [i.id for i in tree.values[0].args]))
      if to_walk is not None:
         for i in ([to_walk] if not isinstance(to_walk, list) else to_walk):
             self.walk(i)
      else:
         for a, b in getattr(tree, '__dict__', {}).items():
            if isinstance(b, list) or 'luaparser.astnodes' in str(b):
               for i in ([b] if not isinstance(b, list) else b):
                   self.walk(i)

把这一切结合在一起:

代码语言:javascript
运行
复制
s = """
function displayText (text)
   print(text)
end

sendGreetings = function(sender, reciever) 
   print("Hi " ..reciever.. " greetings from " ..sender.. "!")
end

displayText("Hello, World!")

sendGreetings("Roger", "Michael")
"""
tree = ast.parse(s)
f = FunCalls()
f.walk(tree)
print(dict(f.f_defs)) #the function definitions with signatures
calls = {a:b for a, b in f.f_calls if any(j == a for j, _ in f.f_defs)}    
print(calls)

输出:

代码语言:javascript
运行
复制
{'displayText': ['text'], 'sendGreetings': ['sender', 'reciever']}
{'displayText': ['Hello, World!'], 'sendGreetings': ['Roger', 'Michael']}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69533439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档