2017-02-13 14 views
0

Я хотел бы проанализировать все объявления функций lua из файла lua. Например, давайте предположим, что у меня есть этот код:Объявление функций Lua Regex

function foo(a, b, c) 
    local d = a + b 
    local e = b - c 
    return d *e 
end 

function boo(person) 
    if (person.age == 18) then 
     print("Adult") 
    else 
     print("Kid") 
    end 

    if (person.money > 20000) then 
     print("Rich") 
    else 
     print("poor") 
    end 
end 

Я хотел бы иметь этот результат:

Group[1]: 
    local d = a + b 
    local e = b - c 
    return d *e 

Group[2]: 
    if (person.age == 18) then 
     print("Adult") 
    else 
     print("Kid") 
    end 

    if (person.money > 20000) then 
     print("Rich") 
    else 
     print("poor") 
    end 

В принципе, я хочу тело функции других слов Everyting между функцией декларацией и последний конец. Однако я пришел к следующему:

(?<=function)(.*?)(?=end) 

Спасибо за ваши ответы.

+1

Это очень сложно, если не невозможно, потому что регулярное выражение обычно не является рекурсивным. –

+0

Если этот язык основан на отступ, он может быть выполнимым. Если нет, тогда вам придется иметь возможность обрабатывать вложенность, т.е. _if если else, если end end_ – sln

ответ

2

Если все ваши определения функций начинаются и заканчиваются в колонке 1, то это работает:

L=[[ 

function foo(a, b, c) 
    local d = a + b 
    local e = b - c 
    return d *e 
end 

function boo(person) 
    if (person.age == 18) then 
     print("Adult") 
    else 
     print("Kid") 
    end 

    if (person.money > 20000) then 
     print("Rich") 
    else 
     print("poor") 
    end 
end 
]] 

for b in L:gmatch("\nfunction.-\n(.-)\nend") do 
    print("------------------") 
    print(b) 
end 

Обратите внимание, что вам нужно пустую строку в верхней части кода, чтобы найти первую функцию.

+2

BTW, эту пустую строку перед первой 'функцией' можно просто добавить перед запуском' gmatch'. –

+0

Хм нормально, но проблема в том, что я не могу быть уверен в том, каким будет выход. Например, функции, которые находятся чуть ниже друг друга (нет пустой пустой строки). Я также забыл упомянуть, что мне нужен Java-код. – x84x4

+1

@ x84x4, код выше не нуждается в пустой извести между функциями, только чтобы они начинались и заканчивались в столбце 1. – lhf

0

Вот некоторые функции, которые выводят тела функций файла, если определения функций начинаются и заканчиваются в первом столбце, и пока функции определены с использованием [local] function ... или [local] fname = function .... Существует также положение для определения определений однострочных функций.

Функция func_bodies() - это итератор, который возвращает таблицы, содержащие строки тел функции. Функция is_func_def() возвращает nil, если line не начинает определение функции. Функция show_funcs() использует итератор и печатает результаты. Обратите внимание, что нет необходимости в пустых строках до или между определениями функций.

function is_func_def (line) 
    return string.match(line, "^function%s+") or 
      string.match(line, "^local%s+function%s+") or 
      string.match(line, "^local%s+[%w_]+%s*=%s*function%s+") or 
      string.match(line, "^[%w_]+%s*=%s*function%s+") 
end 

function func_bodies (file) 
    local body 
    local in_body = false 
    local counter = 0 
    local lines = io.lines(file) 
    return function() 
     for line in lines do 
     if in_body then 
      if string.match(line, "^end") then 
       in_body = false 
       return counter, body 
      else 
       table.insert(body, line) 
      end 
     elseif is_func_def(line) then 
      counter = counter + 1 
      body = {} 
      if string.match(line, "end$") then 
       table.insert(body, string.match(line, "%)%s+(.+)%s+end$")) 
       return counter, body 
      else 
       in_body = true 
      end 
     end 
     end 
     return nil 
    end 
end 

function show_funcs (file) 
    for i, body in func_bodies(file) do 
     io.write(string.format("Group[%d]:\n", i)) 
     for k, v in ipairs(body) do 
     print(v) 
     end 
     print() 
    end 
end 

Вот пример взаимодействия:

> show_funcs("test_funcs3.lua") 
Group[1]: 
    local a = 2*x 
    local b = 2*y 
    return a + b 

Group[2]: 
    local c = x/2 
    local d = y/2 
    return c - d 

Group[3]: 
    local a = x + 1 
    local b = y + 2 
    return a * b 

Group[4]: 
    local a = x - 1 
    local b = y - 2 
    return a/2 - b/2 

Вот файл, используемый для указанного выше теста:

function f_1 (x, y) 
    local a = 2*x 
    local b = 2*y 
    return a + b 
end 
local function f_2 (x, y) 
    local c = x/2 
    local d = y/2 
    return c - d 
end 
g_1 = function (x, y) 
    local a = x + 1 
    local b = y + 2 
    return a * b 
end 
local g_2 = function (x, y) 
    local a = x - 1 
    local b = y - 2 
    return a/2 - b/2 
end 

Вот ваш пример кода с некоторыми функциями однострочных добавлены:

function foo(a, b, c) 
    local d = a + b 
    local e = b - c 
    return d *e 
end 
function boo(person) 
    if (person.age == 18) then 
     print("Adult") 
    else 
     print("Kid") 
    end 

    if (person.money > 20000) then 
     print("Rich") 
    else 
     print("poor") 
    end 
end 

function f1 (x, y) return x + y; end 
local function f2 (x, y) return x - y; end 
g1 = function (x, y) return x * y; end 
local g2 = function (x, y) return x/y; end 

Образец inter действие:

> show_funcs("test_funcs2.lua") 
Group[1]: 
    local d = a + b 
    local e = b - c 
    return d *e 

Group[2]: 
    if (person.age == 18) then 
     print("Adult") 
    else 
     print("Kid") 
    end 

    if (person.money > 20000) then 
     print("Rich") 
    else 
     print("poor") 
    end 

Group[3]: 
return x + y; 

Group[4]: 
return x - y; 

Group[5]: 
return x * y; 

Group[6]: 
return x/y; 
+0

@ x84x4-- Я добавил улучшение в мое решение, чтобы разрешить обнаружение локально локализованных функций. –

+0

Хорошо спасибо, но что, если функция объявлена ​​в одной строке? Кроме того, ваши тестовые функции довольно просты. Означает ли это, что это работает с несколькими заявлениями? – x84x4

+0

Он будет работать с произвольно сложными функциями, если определения начинаются и заканчиваются в первом столбце, а промежуточные строки имеют отступ. Он работает для вашего примера кода. Отдельные функции могут быть добавлены как особый случай. Вложенные определения функций не так просты. –

 Смежные вопросы

  • Нет связанных вопросов^_^