我有一个语法正确的Lua 5.1源代码文件。
我在该文件中有一个位置(行和字符偏移)。
我需要在包含该位置的最内层function()
主体的右括号中获取一个以字节为单位的偏移量(或者确定该位置属于该文件的主要块)。
即:
local function foo() ^ result print("bar") ^ input end
local foo = function() ^ result print("bar") ^ input end
local foo = function() return function() ^ result print("bar") ^ input end end
......等等。
我该如何强有力地做到这一点?
答案 0 :(得分:0)
编辑:我原来的答案没有考虑到最里面的"需求。我考虑到了这一点
使事情变得健壮,"有一些考虑因素。
首先,重要的是跳过字符串和注释内容,以避免在以下情况下输出错误:
foo = function()
print(" function() ")
-- function()
print("bar")
^ input
end
考虑到Lua的嵌套字符串和注释语法,这可能有点困难。例如,考虑输入以嵌套字符串或注释开始的情况:
foo = function()
print([[
bar = function()
print("baz")
^ input
end
]])
end
因此,如果你想要一个完全健壮的系统,那么只能向后解析直到你到达函数参数列表的末尾是不可接受的,因为你可能没有向后解析得足够远以达到[[
会使你的比赛无效。因此,有必要将整个文件解析到您的位置(除非您在这些奇怪的情况下不正确匹配。如果这是一个编辑器插件,这些"不正确&# 34;结果可能实际上是可取的,因为它们允许你使用相同的插件编辑以字符串文字形式存储在其他lua代码中的lua代码。
由于您尝试匹配的特定语法没有任何类型的"嵌套",因此不需要完整的解析器。但是,您需要维护一个堆栈以跟踪范围。考虑到这一点,您需要做的就是从头开始逐个字符地逐步执行源文件,应用以下逻辑:
"
或'
时,请忽略截至结束"
或'
的字符。小心处理\"
和\\
--
时,请忽略评论结束换行符前的字符。如果评论不是多行注释,请注意这样做。[[
,[=[
等),或遇到多行注释符号(例如--[[
或{{1} }等等)忽略字符,直到结束方括号,它们之间有正确数量的匹配等号。--[=[
结尾的块(例如end
,if
,{{1} },while
等。请勿包含for
)。如果是这样,请按下示波器堆栈上的位置。 A"字边界"在这种情况下,任何不能使用lua标识符的字符(这是为了防止像function
这样的情况下的匹配)。文件的开头也被视为单词边界。repeat
,则弹出堆栈的顶部元素。如果堆栈没有元素,则抱怨语法错误。当你最后前进并达到你的输入"位置,从堆栈中弹出元素,直到找到abcfunction()
范围。从该位置前进到下一个end
,忽略评论中的function
(如果它跨越多行或包含内联)
,理论上可以在参数列表中找到评论)。那个位置就是你的结果。
这应该处理每一个案例,包括使用)
句法糖的情况,比如
--[[ ]]
你没有在你的例子中包含但我想你仍然想要匹配。