Lua源代码转换:在给定其大致位置的情况下去除函数调用

时间:2013-08-27 11:49:32

标签: lua

我有一堆Lua 5.1文件,里面有这个(或类似的)构造:

...
local alpha, 
      beta
      = FUNCTION "gamma"
      {
        'delta',
        'epsilon'
      }
...

也就是说,调用FUNCTION返回一个函数,该函数返回一些值,这些值分配给一些局部变量,在现场声明。

确切代码可能会有所不同 - 无论是样式(例如,所有内容都在同一行),还是内容(例如,可以将零参数传递给第二个函数调用)。但总是以local开头,并以两个链式函数调用结束。

我有一个FUNCTION电话号码。我需要找到链中最后一个函数调用的结束(这个特定的一个;在文件的某处可以有更多的FUNCTION调用),并从该点向上删除所有文件内容。

即,之前:

print("foo") -- 01
local alpha = FUNCTION 'beta' -- 02
{ "gamma" } -- 03
print("bar") -- 04

后:

 -- 03
print("bar") -- 04

有关如何处理此问题的任何线索?


更新

为了更清楚天真的正则表达式方法为什么不起作用,这是一个真实的例子:

local alpha
      = FUNCTION ( -- my line number points here
          FUNCTION 'beta' { 'gamma' } ()
            and 'epsilon'
             or 'zeta'
        )
      {
        'eta'
      } -- should be cut from here and above as a result

1 个答案:

答案 0 :(得分:1)

主要想法:搜索相邻的山雀()()

local line_no = 12
local str = [[
print("foo")
local nif_nif
      = FUNCTION (
          FUNCTION 'beta' { 'gamma' } ()
            and 'epsilon'
             or 'zeta'
        )
      {
        'eta'
      }
local nuf_nuf
      = FUNCTION (      -- this is line#12
          FUNCTION 'beta' { 'gamma' } ()
            and 'epsilon'
             or 'zeta'
        )
      {
        'eta'
      }                 -- should be cut from here
local naf_naf
      = FUNCTION (
          FUNCTION 'beta' { 'gamma' } ()
            and 'epsilon'
             or 'zeta'
        )
      {
        'eta'
      }
print("bar")
]]

-- cut all text before target "local" keyword
str = str:gsub('\n','\0',line_no):gsub('^.*(local.-%z)','%1'):gsub('%z','\n')

-- enclose string literals and table constructors into temporary parentheses
str = str:gsub('%b""','(\0%0\0)')
         :gsub("%b''",'(\0%0\0)')
         :gsub("%b{}",'(\0%0\0)')

-- replace text in parentheses with links to it
local n, t = 0, {}
str = str:gsub('%b()', function(s) n=n+1 t[n..'']=s return'<\0'..n..'>' end)

-- search for first chained function call and cut it out
str = str:gsub('^.-<%z%d+>%s*<%z%d+>', '')
repeat
  local ctr
  str, ctr = str:gsub('^%s*<%z%d+>', '')
until ctr == 0

-- replace links with original text
t, str = nil, str:gsub('<%z(%d+)>', t)

-- remove temporary parentheses
str = str:gsub('%(%z', ''):gsub('%z%)', '')

print(str)

输出:

                 -- should be cut from here
local naf_naf
      = FUNCTION (
          FUNCTION 'beta' { 'gamma' } ()
            and 'epsilon'
             or 'zeta'
        )
      {
        'eta'
      }
print("bar")