diff options
-rw-r--r-- | src/matcher/definition.lua | 58 | ||||
-rw-r--r-- | src/matcher/init.lua | 5 | ||||
-rw-r--r-- | src/parser/grammar.lua | 13 | ||||
-rw-r--r-- | test/definition/init.lua | 17 | ||||
-rw-r--r-- | test/main.lua | 16 |
5 files changed, 105 insertions, 4 deletions
diff --git a/src/matcher/definition.lua b/src/matcher/definition.lua new file mode 100644 index 00000000..fe92ae50 --- /dev/null +++ b/src/matcher/definition.lua @@ -0,0 +1,58 @@ +local parser = require 'parser' + +local pos +local defs = {} +local scopes +local result + +local function getResult(name, p) + result = {name, p} + for k in pairs(defs) do + defs[k] = nil + end +end + +local function scopeInit() + scopes = {{}} +end + +local function scopeSet(name, p) + local scope = scopes[#scopes] + scope[name] = p +end + +local function scopeGet(name) + local scope = scopes[#scopes] + return scope[name] +end + +local function checkDifinition(name, p) + if pos < p or pos > p + #name then + return + end + getResult(name, scopeGet(name)) +end + +function defs.Name(p, name) + checkDifinition(name, p) + return name +end + +function defs.LocalVar(p, name) + scopeSet(name, p) +end + +return function (buf, pos_) + pos = pos_ + scopeInit() + parser.grammar(buf, 'Lua', defs) + + if not result then + return nil + end + local name, start = result[1], result[2] + if not start then + return nil + end + return start, start + #name - 1 +end diff --git a/src/matcher/init.lua b/src/matcher/init.lua new file mode 100644 index 00000000..8e2a01e2 --- /dev/null +++ b/src/matcher/init.lua @@ -0,0 +1,5 @@ +local api = { + definition = require 'matcher.definition', +} + +return api diff --git a/src/parser/grammar.lua b/src/parser/grammar.lua index eedbd8da..6f2f9d0a 100644 --- a/src/parser/grammar.lua +++ b/src/parser/grammar.lua @@ -185,7 +185,7 @@ Float16 <- ('.' X16*)? ([pP] [+-]? [1-9]? [0-9]*)? ]] grammar 'Name' [[ -Name <- Sp [a-zA-Z_] [a-zA-Z0-9_]* +Name <- Sp ({} {[a-zA-Z_] [a-zA-Z0-9_]*}) -> Name ]] grammar 'Exp' [[ @@ -233,16 +233,20 @@ TableField <- NewIndex / NewField / Exp NewIndex <- BL Exp BR ASSIGN Exp NewField <- Name ASSIGN Exp -Function <- FUNCTION PL ArgList? PR +Function <- FUNCTION FuncName? PL ArgList? PR (!END Action)* END +FuncName <- FuncPrefix (FuncSuffix)* +FuncPrefix <- Name +FuncSuffix <- DOT Name + / COLON Name -- 纯占位,修改了 `relabel.lua` 使重复定义不抛错 Action <- !. . ]] grammar 'Action' [[ -Action <- SEMICOLON / Do / Break / Return / Label / GoTo / If / For / While / Repeat / Set / Call +Action <- SEMICOLON / Do / Break / Return / Label / GoTo / If / For / While / Repeat / Set / Local / Function / Call ExpList <- Exp (COMMA Exp)* @@ -291,6 +295,9 @@ Repeat <- REPEAT Set <- LOCAL Name ASSIGN Exp / Simple ASSIGN Exp +Local <- LOCAL Function + / LOCAL (Sp {} Name) -> LocalVar + Call <- Prefix (Suffix)* ]] diff --git a/test/definition/init.lua b/test/definition/init.lua new file mode 100644 index 00000000..9ce0b9e7 --- /dev/null +++ b/test/definition/init.lua @@ -0,0 +1,17 @@ +local matcher = require 'matcher' + +local function test(script) + local start = script:find('<!', 1, true) + 2 + local finish = script:find('!>', 1, true) - 1 + local pos = script:find('<?', 1, true) + 2 + local new_script = script:gsub('<[!?]', ' '):gsub('[!?]>', ' ') + + local a, b = matcher.definition(new_script, pos) + assert(a == start) + assert(b == finish) +end + +test [[ +local <!a!> +<?a?> = 1 +]] diff --git a/test/main.lua b/test/main.lua index d8730f09..e14a9b2b 100644 --- a/test/main.lua +++ b/test/main.lua @@ -7,4 +7,18 @@ package.path = package.path .. ';' .. root .. '\\src\\?.lua' require 'filesystem' require 'utility' require 'global_protect' -print('测试') + +local function main() + local function test(name) + local clock = os.clock() + print(('测试[%s]...'):format(name)) + require(name) + print(('测试[%s]用时[%.3f]'):format(name, os.clock() - clock)) + end + + test 'definition' + + print('测试完成') +end + +main() |