summaryrefslogtreecommitdiff
path: root/script/parser
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-11-20 21:55:41 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-11-20 21:55:41 +0800
commitc63b2e404d8d2bb984afe3678a5ba2b2836380cc (patch)
treea70661effacc7a29caa8d49583673ac4be2faaf5 /script/parser
parent85c5a4210e4447422cd5677369ae740ed65725a0 (diff)
downloadlua-language-server-c63b2e404d8d2bb984afe3678a5ba2b2836380cc.zip
remove the old version
Diffstat (limited to 'script/parser')
-rw-r--r--script/parser/ast.lua1913
-rw-r--r--script/parser/calcline.lua93
-rw-r--r--script/parser/grammar.lua630
-rw-r--r--script/parser/init.lua9
-rw-r--r--script/parser/lines.lua190
-rw-r--r--script/parser/parse.lua41
-rw-r--r--script/parser/relabel.lua361
-rw-r--r--script/parser/split.lua9
8 files changed, 0 insertions, 3246 deletions
diff --git a/script/parser/ast.lua b/script/parser/ast.lua
deleted file mode 100644
index af2c76c9..00000000
--- a/script/parser/ast.lua
+++ /dev/null
@@ -1,1913 +0,0 @@
-local tonumber = tonumber
-local string_char = string.char
-local utf8_char = utf8.char
-local type = type
-local table = table
-
-local Errs
-local State
-local function pushError(err)
- if err.finish < err.start then
- err.finish = err.start
- end
- local last = Errs[#Errs]
- if last then
- if last.start <= err.start and last.finish >= err.finish then
- return
- end
- end
- err.level = err.level or 'error'
- Errs[#Errs+1] = err
- return err
-end
-
--- goto 单独处理
-local RESERVED = {
- ['and'] = true,
- ['break'] = true,
- ['do'] = true,
- ['else'] = true,
- ['elseif'] = true,
- ['end'] = true,
- ['false'] = true,
- ['for'] = true,
- ['function'] = true,
- ['if'] = true,
- ['in'] = true,
- ['local'] = true,
- ['nil'] = true,
- ['not'] = true,
- ['or'] = true,
- ['repeat'] = true,
- ['return'] = true,
- ['then'] = true,
- ['true'] = true,
- ['until'] = true,
- ['while'] = true,
-}
-
-local VersionOp = {
- ['&'] = {'Lua 5.3', 'Lua 5.4'},
- ['~'] = {'Lua 5.3', 'Lua 5.4'},
- ['|'] = {'Lua 5.3', 'Lua 5.4'},
- ['<<'] = {'Lua 5.3', 'Lua 5.4'},
- ['>>'] = {'Lua 5.3', 'Lua 5.4'},
- ['//'] = {'Lua 5.3', 'Lua 5.4'},
-}
-
-local function checkOpVersion(op, start)
- local versions = VersionOp[op]
- if not versions then
- return
- end
- for i = 1, #versions do
- if versions[i] == State.Version then
- return
- end
- end
- pushError {
- type = 'UNSUPPORT_SYMBOL',
- start = start,
- finish = start + #op - 1,
- version = versions,
- info = {
- version = State.Version,
- }
- }
-end
-
-local Exp
-
-local function expSplit(list, start, finish, level)
- if start == finish then
- return list[start]
- end
- local info = Exp[level]
- if not info then
- return
- end
- local func = info[1]
- return func(list, start, finish, level)
-end
-
-local function binaryForward(list, start, finish, level)
- local info = Exp[level]
- for i = finish-1, start+2, -1 do
- local op = list[i]
- if info[op] then
- local e1 = expSplit(list, start, i-2, level)
- if not e1 then
- goto CONTINUE
- end
- local e2 = expSplit(list, i+1, finish, level+1)
- if not e2 then
- goto CONTINUE
- end
- checkOpVersion(op, list[i-1])
- return {
- type = 'binary',
- op = op,
- start = e1.start,
- finish = e2.finish,
- [1] = e1,
- [2] = e2,
- }
- end
- ::CONTINUE::
- end
- return expSplit(list, start, finish, level+1)
-end
-
-local function binaryBackward(list, start, finish, level)
- local info = Exp[level]
- for i = start+2, finish-1 do
- local op = list[i]
- if info[op] then
- local e1 = expSplit(list, start, i-2, level+1)
- if not e1 then
- goto CONTINUE
- end
- local e2 = expSplit(list, i+1, finish, level)
- if not e2 then
- goto CONTINUE
- end
- checkOpVersion(op, list[i-1])
- return {
- type = 'binary',
- op = op,
- start = e1.start,
- finish = e2.finish,
- [1] = e1,
- [2] = e2,
- }
- end
- ::CONTINUE::
- end
- return expSplit(list, start, finish, level+1)
-end
-
-local function unary(list, start, finish, level)
- local info = Exp[level]
- local op = list[start+1]
- if info[op] then
- local e1 = expSplit(list, start+2, finish, level)
- if e1 then
- checkOpVersion(op, list[start])
- return {
- type = 'unary',
- op = op,
- start = list[start],
- finish = e1.finish,
- [1] = e1,
- }
- end
- end
- return expSplit(list, start, finish, level+1)
-end
-
-local function checkMissEnd(start)
- if not State.MissEndErr then
- return
- end
- local err = State.MissEndErr
- State.MissEndErr = nil
- local _, finish = State.Lua:find('[%w_]+', start)
- if not finish then
- return
- end
- err.info.related = { start, finish }
- pushError {
- type = 'MISS_END',
- start = start,
- finish = finish,
- }
-end
-
-Exp = {
- {
- ['or'] = true,
- binaryForward,
- },
- {
- ['and'] = true,
- binaryForward,
- },
- {
- ['<='] = true,
- ['>='] = true,
- ['<'] = true,
- ['>'] = true,
- ['~='] = true,
- ['=='] = true,
- binaryForward,
- },
- {
- ['|'] = true,
- binaryForward,
- },
- {
- ['~'] = true,
- binaryForward,
- },
- {
- ['&'] = true,
- binaryForward,
- },
- {
- ['<<'] = true,
- ['>>'] = true,
- binaryForward,
- },
- {
- ['..'] = true,
- binaryBackward,
- },
- {
- ['+'] = true,
- ['-'] = true,
- binaryForward,
- },
- {
- ['*'] = true,
- ['//'] = true,
- ['/'] = true,
- ['%'] = true,
- binaryForward,
- },
- {
- ['^'] = true,
- binaryBackward,
- },
- {
- ['not'] = true,
- ['#'] = true,
- ['~'] = true,
- ['-'] = true,
- unary,
- },
-}
-
-local Defs = {
- Nil = function (pos)
- return {
- type = 'nil',
- start = pos,
- finish = pos + 2,
- }
- end,
- True = function (pos)
- return {
- type = 'boolean',
- start = pos,
- finish = pos + 3,
- [1] = true,
- }
- end,
- False = function (pos)
- return {
- type = 'boolean',
- start = pos,
- finish = pos + 4,
- [1] = false,
- }
- end,
- LongComment = function (beforeEq, afterEq, str, finish, missPos)
- State.Comments[#State.Comments+1] = {
- start = beforeEq,
- finish = finish,
- }
- if missPos then
- local endSymbol = ']' .. ('='):rep(afterEq-beforeEq) .. ']'
- local s, _, w = str:find('(%][%=]*%])[%c%s]*$')
- if s then
- pushError {
- type = 'ERR_LCOMMENT_END',
- start = missPos - #str + s - 1,
- finish = missPos - #str + s + #w - 2,
- info = {
- symbol = endSymbol,
- },
- fix = {
- title = 'FIX_LCOMMENT_END',
- {
- start = missPos - #str + s - 1,
- finish = missPos - #str + s + #w - 2,
- text = endSymbol,
- }
- },
- }
- end
- pushError {
- type = 'MISS_SYMBOL',
- start = missPos,
- finish = missPos,
- info = {
- symbol = endSymbol,
- },
- fix = {
- title = 'ADD_LCOMMENT_END',
- {
- start = missPos,
- finish = missPos,
- text = endSymbol,
- }
- },
- }
- end
- end,
- CLongComment = function (start1, finish1, start2, finish2)
- pushError {
- type = 'ERR_C_LONG_COMMENT',
- start = start1,
- finish = finish2 - 1,
- fix = {
- title = 'FIX_C_LONG_COMMENT',
- {
- start = start1,
- finish = finish1 - 1,
- text = '--[[',
- },
- {
- start = start2,
- finish = finish2 - 1,
- text = '--]]'
- },
- }
- }
- end,
- CCommentPrefix = function (start, finish)
- pushError {
- type = 'ERR_COMMENT_PREFIX',
- start = start,
- finish = finish - 1,
- fix = {
- title = 'FIX_COMMENT_PREFIX',
- {
- start = start,
- finish = finish - 1,
- text = '--',
- },
- }
- }
- return false
- end,
- String = function (start, quote, str, finish)
- return {
- type = 'string',
- start = start,
- finish = finish - 1,
- [1] = str,
- [2] = quote,
- }
- end,
- LongString = function (beforeEq, afterEq, str, missPos)
- if missPos then
- local endSymbol = ']' .. ('='):rep(afterEq-beforeEq) .. ']'
- local s, _, w = str:find('(%][%=]*%])[%c%s]*$')
- if s then
- pushError {
- type = 'ERR_LSTRING_END',
- start = missPos - #str + s - 1,
- finish = missPos - #str + s + #w - 2,
- info = {
- symbol = endSymbol,
- },
- fix = {
- title = 'FIX_LSTRING_END',
- {
- start = missPos - #str + s - 1,
- finish = missPos - #str + s + #w - 2,
- text = endSymbol,
- }
- },
- }
- end
- pushError {
- type = 'MISS_SYMBOL',
- start = missPos,
- finish = missPos,
- info = {
- symbol = endSymbol,
- },
- fix = {
- title = 'ADD_LSTRING_END',
- {
- start = missPos,
- finish = missPos,
- text = endSymbol,
- }
- },
- }
- end
- return '[' .. ('='):rep(afterEq-beforeEq) .. '[', str
- end,
- Char10 = function (char)
- char = tonumber(char)
- if not char or char < 0 or char > 255 then
- return ''
- end
- return string_char(char)
- end,
- Char16 = function (pos, char)
- if State.Version == 'Lua 5.1' then
- pushError {
- type = 'ERR_ESC',
- start = pos-1,
- finish = pos,
- version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
- info = {
- version = State.Version,
- }
- }
- return char
- end
- return string_char(tonumber(char, 16))
- end,
- CharUtf8 = function (pos, char)
- if State.Version ~= 'Lua 5.3'
- and State.Version ~= 'Lua 5.4'
- and State.Version ~= 'LuaJIT'
- then
- pushError {
- type = 'ERR_ESC',
- start = pos-3,
- finish = pos-2,
- version = {'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
- info = {
- version = State.Version,
- }
- }
- return char
- end
- if #char == 0 then
- pushError {
- type = 'UTF8_SMALL',
- start = pos-3,
- finish = pos,
- }
- return ''
- end
- local v = tonumber(char, 16)
- if not v then
- for i = 1, #char do
- if not tonumber(char:sub(i, i), 16) then
- pushError {
- type = 'MUST_X16',
- start = pos + i - 1,
- finish = pos + i - 1,
- }
- end
- end
- return ''
- end
- if State.Version == 'Lua 5.4' then
- if v < 0 or v > 0x7FFFFFFF then
- pushError {
- type = 'UTF8_MAX',
- start = pos-3,
- finish = pos+#char,
- info = {
- min = '00000000',
- max = '7FFFFFFF',
- }
- }
- end
- else
- if v < 0 or v > 0x10FFFF then
- pushError {
- type = 'UTF8_MAX',
- start = pos-3,
- finish = pos+#char,
- version = v <= 0x7FFFFFFF and 'Lua 5.4' or nil,
- info = {
- min = '000000',
- max = '10FFFF',
- }
- }
- end
- end
- if v >= 0 and v <= 0x10FFFF then
- return utf8_char(v)
- end
- return ''
- end,
- Number = function (start, number, finish)
- local n = tonumber(number)
- if n then
- State.LastNumber = {
- type = 'number',
- start = start,
- finish = finish - 1,
- [1] = n,
- [2] = number,
- }
- return State.LastNumber
- else
- pushError {
- type = 'MALFORMED_NUMBER',
- start = start,
- finish = finish - 1,
- }
- State.LastNumber = {
- type = 'number',
- start = start,
- finish = finish - 1,
- [1] = 0,
- }
- return State.LastNumber
- end
- end,
- FFINumber = function (start, symbol)
- if math.type(State.LastNumber[1]) == 'float' then
- pushError {
- type = 'UNKNOWN_SYMBOL',
- start = start,
- finish = start + #symbol - 1,
- info = {
- symbol = symbol,
- }
- }
- State.LastNumber[1] = 0
- return
- end
- if State.Version ~= 'LuaJIT' then
- pushError {
- type = 'UNSUPPORT_SYMBOL',
- start = start,
- finish = start + #symbol - 1,
- version = 'LuaJIT',
- info = {
- version = State.Version,
- }
- }
- State.LastNumber[1] = 0
- end
- end,
- ImaginaryNumber = function (start, symbol)
- if State.Version ~= 'LuaJIT' then
- pushError {
- type = 'UNSUPPORT_SYMBOL',
- start = start,
- finish = start + #symbol - 1,
- version = 'LuaJIT',
- info = {
- version = State.Version,
- }
- }
- end
- State.LastNumber[1] = 0
- end,
- Name = function (start, str, finish)
- local isKeyWord
- if RESERVED[str] then
- isKeyWord = true
- elseif str == 'goto' then
- if State.Version ~= 'Lua 5.1' and State.Version ~= 'LuaJIT' then
- isKeyWord = true
- end
- end
- if isKeyWord then
- pushError {
- type = 'KEYWORD',
- start = start,
- finish = finish - 1,
- }
- end
- return {
- type = 'name',
- start = start,
- finish = finish - 1,
- [1] = str,
- }
- end,
- Simple = function (first, ...)
- if ... then
- local obj = {
- type = 'simple',
- start = first.start,
- first, ...,
- }
- local last = obj[#obj]
- obj.finish = last.finish
- return obj
- elseif first == '' then
- return nil
- else
- return first
- end
- end,
- SimpleCall = function (simple)
- if not simple then
- return nil
- end
- if simple.type ~= 'simple' then
- pushError {
- type = 'EXP_IN_ACTION',
- start = simple.start,
- finish = simple.finish,
- }
- return simple
- end
- local last = simple[#simple]
- if last.type == 'call' then
- return simple
- end
- local colon = simple[#simple-1]
- if colon and colon.type == ':' then
- -- 型如 `obj:method`,将错误让给MISS_SYMBOL
- return simple
- end
- pushError {
- type = 'EXP_IN_ACTION',
- start = simple[1].start,
- finish = last.finish,
- }
- return simple
- end,
- Exp = function (first, ...)
- if not ... then
- return first
- end
- local list = {first, ...}
- return expSplit(list, 1, #list, 1)
- end,
- Prefix = function (start, exp, finish)
- exp.brackets = true
- return exp
- end,
- Index = function (start, exp, finish)
- return {
- type = 'index',
- start = start,
- finish = finish - 1,
- [1] = exp,
- }
- end,
- Call = function (start, arg, finish)
- if arg == nil then
- return {
- type = 'call',
- start = start,
- finish = finish - 1,
- }
- end
- if arg.type == 'list' then
- arg.type = 'call'
- arg.start = start
- arg.finish = finish - 1
- return arg
- end
- local obj = {
- type = 'call',
- start = start,
- finish = finish - 1,
- [1] = arg,
- }
- return obj
- end,
- DOTS = function (start)
- return {
- type = '...',
- start = start,
- finish = start + 2,
- }
- end,
- DotsAsArg = function (obj)
- State.Dots[#State.Dots] = true
- return obj
- end,
- DotsAsExp = function (obj)
- if not State.Dots[#State.Dots] then
- pushError {
- type = 'UNEXPECT_DOTS',
- start = obj.start,
- finish = obj.finish,
- }
- end
- return obj
- end,
- COLON = function (start)
- return {
- type = ':',
- start = start,
- finish = start,
- }
- end,
- DOT = function (start)
- return {
- type = '.',
- start = start,
- finish = start,
- }
- end,
- Function = function (start, argStart, arg, argFinish, ...)
- local obj = {
- type = 'function',
- start = start,
- arg = arg,
- argStart = argStart - 1,
- argFinish = argFinish,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- if obj.argFinish > obj.finish then
- obj.argFinish = obj.finish
- end
- checkMissEnd(start)
- return obj
- end,
- NamedFunction = function (start, name, argStart, arg, argFinish, ...)
- local obj = {
- type = 'function',
- start = start,
- name = name,
- arg = arg,
- argStart = argStart - 1,
- argFinish = argFinish,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- if obj.argFinish > obj.finish then
- obj.argFinish = obj.finish
- end
- checkMissEnd(start)
- return obj
- end,
- LocalFunction = function (start, name, argStart, arg, argFinish, ...)
- local obj = {
- type = 'localfunction',
- start = start,
- name = name,
- arg = arg,
- argStart = argStart - 1,
- argFinish = argFinish,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- if obj.argFinish > obj.finish then
- obj.argFinish = obj.finish
- end
-
- if name.type ~= 'name' then
- pushError {
- type = 'UNEXPECT_LFUNC_NAME',
- start = name.start,
- finish = name.finish,
- }
- end
-
- checkMissEnd(start)
- return obj
- end,
- Table = function (start, ...)
- local args = {...}
- local max = #args
- local finish = args[max] - 1
- local table = {
- type = 'table',
- start = start,
- finish = finish
- }
- start = start + 1
- local wantField = true
- for i = 1, max-1 do
- local arg = args[i]
- local isField = type(arg) == 'table'
- local isEmmy = isField and arg.type:sub(1, 4) == 'emmy'
- if wantField and not isField then
- pushError {
- type = 'MISS_EXP',
- start = start,
- finish = arg - 1,
- }
- elseif not wantField and isField and not isEmmy then
- pushError {
- type = 'MISS_SEP_IN_TABLE',
- start = start,
- finish = arg.start-1,
- }
- end
- if isField then
- table[#table+1] = arg
- if not isEmmy then
- wantField = false
- start = arg.finish + 1
- end
- else
- wantField = true
- start = arg
- end
- end
- return table
- end,
- NewField = function (key, value)
- return {
- type = 'pair',
- start = key.start,
- finish = value.finish,
- key, value,
- }
- end,
- NewIndex = function (key, value)
- return {
- type = 'pair',
- start = key.start,
- finish = value.finish,
- key, value,
- }
- end,
- List = function (first, second, ...)
- if second then
- local list = {
- type = 'list',
- start = first.start,
- first, second, ...
- }
- local last = list[#list]
- list.finish = last.finish
- return list
- elseif type(first) == 'table' then
- return first
- else
- return nil
- end
- end,
- ArgList = function (...)
- if ... == '' then
- return nil
- end
- local args = table.pack(...)
- local list = {}
- local max = args.n
- args.n = nil
- local wantName = true
- for i = 1, max do
- local obj = args[i]
- if type(obj) == 'number' then
- if wantName then
- pushError {
- type = 'MISS_NAME',
- start = obj,
- finish = obj,
- }
- end
- wantName = true
- else
- if not wantName then
- pushError {
- type = 'MISS_SYMBOL',
- start = obj.start-1,
- finish = obj.start-1,
- info = {
- symbol = ',',
- }
- }
- end
- wantName = false
- list[#list+1] = obj
- if obj.type == '...' then
- if i < max then
- local a = args[i+1]
- local b = args[max]
- pushError {
- type = 'ARGS_AFTER_DOTS',
- start = type(a) == 'number' and a or a.start,
- finish = type(b) == 'number' and b or b.finish,
- }
- end
- break
- end
- end
- end
- if wantName then
- local last = args[max]
- pushError {
- type = 'MISS_NAME',
- start = last+1,
- finish = last+1,
- }
- end
- if #list == 0 then
- return nil
- elseif #list == 1 then
- return list[1]
- else
- list.type = 'list'
- list.start = list[1].start
- list.finish = list[#list].finish
- return list
- end
- end,
- CallArgList = function (start, ...)
- local args = {...}
- local max = #args
- local finish = args[max] - 1
- local exps = {
- type = 'list',
- start = start,
- finish = finish,
- }
- local wantExp = true
- for i = 1, max-1 do
- local arg = args[i]
- local isExp = type(arg) == 'table'
- if wantExp and not isExp then
- pushError {
- type = 'MISS_EXP',
- start = start,
- finish = arg - 1,
- }
- elseif not wantExp and isExp then
- pushError {
- type = 'MISS_SYMBOL',
- start = start,
- finish = arg.start-1,
- info = {
- symbol = ',',
- }
- }
- end
- if isExp then
- exps[#exps+1] = arg
- wantExp = false
- start = arg.finish + 1
- else
- wantExp = true
- start = arg
- end
- end
- if wantExp then
- pushError {
- type = 'MISS_EXP',
- start = start,
- finish = finish,
- }
- end
- if #exps == 0 then
- return nil
- elseif #exps == 1 then
- return exps[1]
- else
- return exps
- end
- end,
- Nothing = function ()
- return nil
- end,
- None = function()
- return
- end,
- Skip = function ()
- return false
- end,
- Set = function (keys, values)
- return {
- type = 'set',
- keys, values,
- }
- end,
- LocalTag = function (...)
- if not ... or ... == '' then
- return nil
- end
- local tags = {...}
- for i, tag in ipairs(tags) do
- if State.Version ~= 'Lua 5.4' then
- pushError {
- type = 'UNSUPPORT_SYMBOL',
- start = tag.start,
- finish = tag.finish,
- version = 'Lua 5.4',
- info = {
- version = State.Version,
- }
- }
- elseif tag[1] ~= 'const' and tag[1] ~= 'close' then
- pushError {
- type = 'UNKNOWN_TAG',
- start = tag.start,
- finish = tag.finish,
- info = {
- tag = tag[1],
- }
- }
- elseif i > 1 then
- pushError {
- type = 'MULTI_TAG',
- start = tag.start,
- finish = tag.finish,
- info = {
- tag = tag[1],
- }
- }
- end
- end
- return tags
- end,
- LocalName = function (name, tags)
- name.tags = tags
- return name
- end,
- Local = function (keys, values)
- return {
- type = 'local',
- keys, values,
- }
- end,
- DoBody = function (...)
- if ... == '' then
- return {
- type = 'do',
- }
- else
- return {
- type = 'do',
- ...
- }
- end
- end,
- Do = function (start, action, finish)
- action.start = start
- action.finish = finish - 1
- checkMissEnd(start)
- return action
- end,
- Break = function (finish, ...)
- if State.Break > 0 then
- local breakChunk = {
- type = 'break',
- }
- if not ... then
- return breakChunk
- end
- local action = select(-1, ...)
- if not action then
- return breakChunk
- end
- if State.Version == 'Lua 5.1' or State.Version == 'LuaJIT' then
- pushError {
- type = 'ACTION_AFTER_BREAK',
- start = finish - #'break',
- finish = finish - 1,
- }
- end
- return breakChunk, action
- else
- pushError {
- type = 'BREAK_OUTSIDE',
- start = finish - #'break',
- finish = finish - 1,
- }
- if not ... then
- return false
- end
- local action = select(-1, ...)
- if not action then
- return false
- end
- return action
- end
- end,
- BreakStart = function ()
- State.Break = State.Break + 1
- end,
- BreakEnd = function ()
- State.Break = State.Break - 1
- end,
- Return = function (start, exp, finish)
- if not finish then
- finish = exp
- exp = {
- type = 'return',
- start = start,
- finish = finish - 1,
- }
- else
- if exp.type == 'list' then
- exp.type = 'return'
- exp.start = start
- exp.finish = finish - 1
- else
- exp = {
- type = 'return',
- start = start,
- finish = finish - 1,
- [1] = exp,
- }
- end
- end
- return exp
- end,
- Label = function (start, name, finish)
- if State.Version == 'Lua 5.1' then
- pushError {
- type = 'UNSUPPORT_SYMBOL',
- start = start,
- finish = finish - 1,
- version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
- info = {
- version = State.Version,
- }
- }
- return false
- end
- name.type = 'label'
- local labels = State.Label[#State.Label]
- local str = name[1]
- if labels[str] then
- --pushError {
- -- type = 'REDEFINE_LABEL',
- -- start = name.start,
- -- finish = name.finish,
- -- info = {
- -- label = str,
- -- related = {labels[str].start, labels[str].finish},
- -- }
- --}
- else
- labels[str] = name
- end
- return name
- end,
- GoTo = function (start, name, finish)
- if State.Version == 'Lua 5.1' then
- pushError {
- type = 'UNSUPPORT_SYMBOL',
- start = start,
- finish = finish - 1,
- version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
- info = {
- version = State.Version,
- }
- }
- return false
- end
- name.type = 'goto'
- local labels = State.Label[#State.Label]
- labels[#labels+1] = name
- return name
- end,
- -- TODO 这里的检查不完整,但是完整的检查比较复杂,开销比较高
- -- 不能jump到另一个局部变量的作用域
- -- 函数会切断goto与label
- -- 不能从block外jump到block内,但是可以从block内jump到block外
- BlockStart = function ()
- State.Label[#State.Label+1] = {}
- State.Dots[#State.Dots+1] = false
- end,
- BlockEnd = function ()
- local labels = State.Label[#State.Label]
- State.Label[#State.Label] = nil
- State.Dots[#State.Dots] = nil
- for i = 1, #labels do
- local name = labels[i]
- local str = name[1]
- if not labels[str] then
- pushError {
- type = 'NO_VISIBLE_LABEL',
- start = name.start,
- finish = name.finish,
- info = {
- label = str,
- }
- }
- end
- end
- end,
- IfBlock = function (exp, start, ...)
- local obj = {
- filter = exp,
- start = start,
- ...
- }
- local max = #obj
- obj.finish = obj[max]
- obj[max] = nil
- return obj
- end,
- ElseIfBlock = function (exp, start, ...)
- local obj = {
- filter = exp,
- start = start,
- ...
- }
- local max = #obj
- obj.finish = obj[max]
- obj[max] = nil
- return obj
- end,
- ElseBlock = function (start, ...)
- local obj = {
- start = start,
- ...
- }
- local max = #obj
- obj.finish = obj[max]
- obj[max] = nil
- return obj
- end,
- If = function (start, ...)
- local obj = {
- type = 'if',
- start = start,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- checkMissEnd(start)
- return obj
- end,
- Loop = function (start, arg, min, max, step, ...)
- local obj = {
- type = 'loop',
- start = start,
- arg = arg,
- min = min,
- max = max,
- step = step,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- checkMissEnd(start)
- return obj
- end,
- In = function (start, arg, exp, ...)
- local obj = {
- type = 'in',
- start = start,
- arg = arg,
- exp = exp,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- checkMissEnd(start)
- return obj
- end,
- While = function (start, filter, ...)
- local obj = {
- type = 'while',
- start = start,
- filter = filter,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj[max] = nil
- checkMissEnd(start)
- return obj
- end,
- Repeat = function (start, ...)
- local obj = {
- type = 'repeat',
- start = start,
- ...
- }
- local max = #obj
- obj.finish = obj[max] - 1
- obj.filter = obj[max-1]
- obj[max] = nil
- obj[max-1] = nil
- return obj
- end,
- Lua = function (...)
- if ... == '' then
- return {}
- end
- return {...}
- end,
-
- -- EmmyLua 支持
- EmmyName = function (start, str)
- return {
- type = 'emmyName',
- start = start,
- finish = start + #str - 1,
- [1] = str,
- }
- end,
- DirtyEmmyName = function (pos)
- pushError {
- type = 'MISS_NAME',
- level = 'warning',
- start = pos,
- finish = pos,
- }
- return {
- type = 'emmyName',
- start = pos-1,
- finish = pos-1,
- [1] = ''
- }
- end,
- EmmyClass = function (class, startPos, extends)
- if extends and extends[1] == '' then
- extends.start = startPos
- end
- return {
- type = 'emmyClass',
- start = class.start,
- finish = (extends or class).finish,
- [1] = class,
- [2] = extends,
- }
- end,
- EmmyType = function (typeDef)
- return typeDef
- end,
- EmmyCommonType = function (...)
- local result = {
- type = 'emmyType',
- ...
- }
- for i = 1, #result // 2 do
- local startPos = result[i * 2]
- local emmyName = result[i * 2 + 1]
- if emmyName[1] == '' then
- emmyName.start = startPos
- end
- result[i + 1] = emmyName
- end
- for i = #result // 2 + 2, #result do
- result[i] = nil
- end
- result.start = result[1].start
- result.finish = result[#result].finish
- return result
- end,
- EmmyArrayType = function (start, emmy, _, finish)
- emmy.type = 'emmyArrayType'
- emmy.start = start
- emmy.finish = finish - 1
- return emmy
- end,
- EmmyTableType = function (start, keyType, valueType, finish)
- return {
- type = 'emmyTableType',
- start = start,
- finish = finish - 1,
- [1] = keyType,
- [2] = valueType,
- }
- end,
- EmmyFunctionType = function (start, args, returns, finish)
- local result = {
- start = start,
- finish = finish - 1,
- type = 'emmyFunctionType',
- args = args,
- returns = returns,
- }
- return result
- end,
- EmmyFunctionRtns = function (...)
- return {...}
- end,
- EmmyFunctionArgs = function (...)
- local args = {...}
- args[#args] = nil
- return args
- end,
- EmmyAlias = function (name, emmyName, ...)
- return {
- type = 'emmyAlias',
- start = name.start,
- finish = emmyName.finish,
- name,
- emmyName,
- ...
- }
- end,
- EmmyParam = function (argName, emmyName, option, ...)
- local emmy = {
- type = 'emmyParam',
- option = option,
- argName,
- emmyName,
- ...
- }
- emmy.start = emmy[1].start
- emmy.finish = emmy[#emmy].finish
- return emmy
- end,
- EmmyReturn = function (start, type, name, finish, option)
- local emmy = {
- type = 'emmyReturn',
- option = option,
- start = start,
- finish = finish - 1,
- [1] = type,
- [2] = name,
- }
- return emmy
- end,
- EmmyField = function (access, fieldName, ...)
- local obj = {
- type = 'emmyField',
- access, fieldName,
- ...
- }
- obj.start = obj[2].start
- obj.finish = obj[3].finish
- return obj
- end,
- EmmyGenericBlock = function (genericName, parentName)
- return {
- start = genericName.start,
- finish = parentName and parentName.finish or genericName.finish,
- genericName,
- parentName,
- }
- end,
- EmmyGeneric = function (...)
- local emmy = {
- type = 'emmyGeneric',
- ...
- }
- emmy.start = emmy[1].start
- emmy.finish = emmy[#emmy].finish
- return emmy
- end,
- EmmyVararg = function (typeName)
- return {
- type = 'emmyVararg',
- start = typeName.start,
- finish = typeName.finish,
- typeName,
- }
- end,
- EmmyLanguage = function (language)
- return {
- type = 'emmyLanguage',
- start = language.start,
- finish = language.finish,
- language,
- }
- end,
- EmmySee = function (start, className, methodName, finish)
- return {
- type = 'emmySee',
- start = start,
- finish = finish - 1,
- className, methodName
- }
- end,
- EmmyOverLoad = function (EmmyFunctionType)
- EmmyFunctionType.type = 'emmyOverLoad'
- return EmmyFunctionType
- end,
- EmmyIncomplete = function (emmyName)
- emmyName.type = 'emmyIncomplete'
- return emmyName
- end,
- EmmyComment = function (...)
- local lines = {...}
- for i = 2, #lines do
- local line = lines[i]
- if line:sub(1, 1) == '|' then
- lines[i] = '\n' .. line:sub(2)
- end
- end
- return {
- type = 'emmyComment',
- [1] = table.concat(lines, '\n'),
- }
- end,
- EmmyOption = function (options)
- if not options or options == '' then
- return nil
- end
- local option = {}
- for _, pair in ipairs(options) do
- if pair.type == 'pair' then
- local key = pair[1]
- local value = pair[2]
- if key.type == 'name' then
- option[key[1]] = value[1]
- end
- end
- end
- return option
- end,
- EmmyTypeEnum = function (default, enum, comment)
- enum.type = 'emmyEnum'
- if default ~= '' then
- enum.default = true
- end
- enum.comment = comment
- return enum
- end,
-
- -- 捕获错误
- UnknownSymbol = function (start, symbol)
- pushError {
- type = 'UNKNOWN_SYMBOL',
- start = start,
- finish = start + #symbol - 1,
- info = {
- symbol = symbol,
- }
- }
- return
- end,
- UnknownAction = function (start, symbol)
- pushError {
- type = 'UNKNOWN_SYMBOL',
- start = start,
- finish = start + #symbol - 1,
- info = {
- symbol = symbol,
- }
- }
- return false
- end,
- DirtyName = function (pos)
- pushError {
- type = 'MISS_NAME',
- start = pos,
- finish = pos,
- }
- return {
- type = 'name',
- start = pos-1,
- finish = pos-1,
- [1] = ''
- }
- end,
- DirtyExp = function (pos)
- pushError {
- type = 'MISS_EXP',
- start = pos,
- finish = pos,
- }
- return {
- type = 'name',
- start = pos,
- finish = pos,
- [1] = ''
- }
- end,
- MissExp = function (pos)
- pushError {
- type = 'MISS_EXP',
- start = pos,
- finish = pos,
- }
- end,
- MissExponent = function (start, finish)
- pushError {
- type = 'MISS_EXPONENT',
- start = start,
- finish = finish - 1,
- }
- end,
- MissQuote1 = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = '"'
- }
- }
- end,
- MissQuote2 = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = "'"
- }
- }
- end,
- MissEscX = function (pos)
- pushError {
- type = 'MISS_ESC_X',
- start = pos-2,
- finish = pos+1,
- }
- end,
- MissTL = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = '{',
- }
- }
- end,
- MissTR = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = '}',
- }
- }
- return pos + 1
- end,
- MissBR = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = ']',
- }
- }
- return pos + 1
- end,
- MissPL = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = '(',
- }
- }
- end,
- DirtyPR = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = ')',
- }
- }
- return pos + 1
- end,
- MissPR = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = ')',
- }
- }
- end,
- ErrEsc = function (pos)
- pushError {
- type = 'ERR_ESC',
- start = pos-1,
- finish = pos,
- }
- end,
- MustX16 = function (pos, str)
- pushError {
- type = 'MUST_X16',
- start = pos,
- finish = pos + #str - 1,
- }
- end,
- MissAssign = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = '=',
- }
- }
- end,
- MissTableSep = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = ','
- }
- }
- end,
- MissField = function (pos)
- pushError {
- type = 'MISS_FIELD',
- start = pos,
- finish = pos,
- }
- end,
- MissMethod = function (pos)
- pushError {
- type = 'MISS_METHOD',
- start = pos,
- finish = pos,
- }
- end,
- MissLabel = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = '::',
- }
- }
- end,
- MissEnd = function (pos)
- State.MissEndErr = pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = 'end',
- }
- }
- end,
- MissDo = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = 'do',
- }
- }
- end,
- MissComma = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = ',',
- }
- }
- end,
- MissIn = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = 'in',
- }
- }
- end,
- MissUntil = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = 'until',
- }
- }
- end,
- MissThen = function (pos)
- pushError {
- type = 'MISS_SYMBOL',
- start = pos,
- finish = pos,
- info = {
- symbol = 'then',
- }
- }
- end,
- ExpInAction = function (start, exp, finish)
- pushError {
- type = 'EXP_IN_ACTION',
- start = start,
- finish = finish - 1,
- }
- return exp
- end,
- AfterReturn = function (rtn, ...)
- if not ... then
- return rtn
- end
- local action = select(-1, ...)
- if not action then
- return rtn
- end
- pushError {
- type = 'ACTION_AFTER_RETURN',
- start = rtn.start,
- finish = rtn.finish,
- }
- return rtn, action
- end,
- MissIf = function (start, block)
- pushError {
- type = 'MISS_SYMBOL',
- start = start,
- finish = start,
- info = {
- symbol = 'if',
- }
- }
- return block
- end,
- MissGT = function (start)
- pushError {
- type = 'MISS_SYMBOL',
- start = start,
- finish = start,
- info = {
- symbol = '>'
- }
- }
- end,
- ErrAssign = function (start, finish)
- pushError {
- type = 'ERR_ASSIGN_AS_EQ',
- start = start,
- finish = finish - 1,
- fix = {
- title = 'FIX_ASSIGN_AS_EQ',
- {
- start = start,
- finish = finish - 1,
- text = '=',
- }
- }
- }
- end,
- ErrEQ = function (start, finish)
- pushError {
- type = 'ERR_EQ_AS_ASSIGN',
- start = start,
- finish = finish - 1,
- fix = {
- title = 'FIX_EQ_AS_ASSIGN',
- {
- start = start,
- finish = finish - 1,
- text = '==',
- }
- }
- }
- return '=='
- end,
- ErrUEQ = function (start, finish)
- pushError {
- type = 'ERR_UEQ',
- start = start,
- finish = finish - 1,
- fix = {
- title = 'FIX_UEQ',
- {
- start = start,
- finish = finish - 1,
- text = '~=',
- }
- }
- }
- return '=='
- end,
- ErrThen = function (start, finish)
- pushError {
- type = 'ERR_THEN_AS_DO',
- start = start,
- finish = finish - 1,
- fix = {
- title = 'FIX_THEN_AS_DO',
- {
- start = start,
- finish = finish - 1,
- text = 'then',
- }
- }
- }
- end,
- ErrDo = function (start, finish)
- pushError {
- type = 'ERR_DO_AS_THEN',
- start = start,
- finish = finish - 1,
- fix = {
- title = 'FIX_DO_AS_THEN',
- {
- start = start,
- finish = finish - 1,
- text = 'do',
- }
- }
- }
- end,
-}
-
-local function init(state, errs)
- State = state
- Errs = errs
-end
-
-return {
- defs = Defs,
- init = init,
-}
diff --git a/script/parser/calcline.lua b/script/parser/calcline.lua
deleted file mode 100644
index 26f475d9..00000000
--- a/script/parser/calcline.lua
+++ /dev/null
@@ -1,93 +0,0 @@
-local m = require 'lpeglabel'
-
-local row
-local fl
-local NL = (m.P'\r\n' + m.S'\r\n') * m.Cp() / function (pos)
- row = row + 1
- fl = pos
-end
-local ROWCOL = (NL + m.P(1))^0
-local function rowcol(str, n)
- row = 1
- fl = 1
- ROWCOL:match(str:sub(1, n))
- local col = n - fl + 1
- return row, col
-end
-
-local function rowcol_utf8(str, n)
- row = 1
- fl = 1
- ROWCOL:match(str:sub(1, n))
- return row, utf8.len(str, fl, n)
-end
-
-local function position(str, _row, _col)
- local cur = 1
- local row = 1
- while true do
- if row == _row then
- return cur + _col - 1
- elseif row > _row then
- return cur - 1
- end
- local pos = str:find('[\r\n]', cur)
- if not pos then
- return #str
- end
- row = row + 1
- if str:sub(pos, pos+1) == '\r\n' then
- cur = pos + 2
- else
- cur = pos + 1
- end
- end
-end
-
-local function position_utf8(str, _row, _col)
- local cur = 1
- local row = 1
- while true do
- if row == _row then
- return utf8.offset(str, _col, cur)
- elseif row > _row then
- return cur - 1
- end
- local pos = str:find('[\r\n]', cur)
- if not pos then
- return #str
- end
- row = row + 1
- if str:sub(pos, pos+1) == '\r\n' then
- cur = pos + 2
- else
- cur = pos + 1
- end
- end
-end
-
-local NL = m.P'\r\n' + m.S'\r\n'
-
-local function line(str, row)
- local count = 0
- local res
- local LINE = m.Cmt((1 - NL)^0, function (_, _, c)
- count = count + 1
- if count == row then
- res = c
- return false
- end
- return true
- end)
- local MATCH = (LINE * NL)^0 * LINE
- MATCH:match(str)
- return res
-end
-
-return {
- rowcol = rowcol,
- rowcol_utf8 = rowcol_utf8,
- position = position,
- position_utf8 = position_utf8,
- line = line,
-}
diff --git a/script/parser/grammar.lua b/script/parser/grammar.lua
deleted file mode 100644
index e5d5ee69..00000000
--- a/script/parser/grammar.lua
+++ /dev/null
@@ -1,630 +0,0 @@
-local re = require 'parser.relabel'
-local m = require 'lpeglabel'
-local ast = require 'parser.ast'
-
-local scriptBuf = ''
-local compiled = {}
-local parser
-local defs = ast.defs
-
--- goto 可以作为名字,合法性之后处理
-local RESERVED = {
- ['and'] = true,
- ['break'] = true,
- ['do'] = true,
- ['else'] = true,
- ['elseif'] = true,
- ['end'] = true,
- ['false'] = true,
- ['for'] = true,
- ['function'] = true,
- ['if'] = true,
- ['in'] = true,
- ['local'] = true,
- ['nil'] = true,
- ['not'] = true,
- ['or'] = true,
- ['repeat'] = true,
- ['return'] = true,
- ['then'] = true,
- ['true'] = true,
- ['until'] = true,
- ['while'] = true,
-}
-
-defs.nl = (m.P'\r\n' + m.S'\r\n')
-defs.s = m.S' \t'
-defs.S = - defs.s
-defs.ea = '\a'
-defs.eb = '\b'
-defs.ef = '\f'
-defs.en = '\n'
-defs.er = '\r'
-defs.et = '\t'
-defs.ev = '\v'
-defs['nil'] = m.Cp() / function () return nil end
-defs['false'] = m.Cp() / function () return false end
-defs.NotReserved = function (_, _, str)
- if RESERVED[str] then
- return false
- end
- return true
-end
-defs.Reserved = function (_, _, str)
- if RESERVED[str] then
- return true
- end
- return false
-end
-defs.None = function () end
-defs.np = m.Cp() / function (n) return n+1 end
-
-m.setmaxstack(1000)
-
-local eof = re.compile '!. / %{SYNTAX_ERROR}'
-
-local function grammar(tag)
- return function (script)
- scriptBuf = script .. '\r\n' .. scriptBuf
- compiled[tag] = re.compile(scriptBuf, defs) * eof
- end
-end
-
-local function errorpos(pos, err)
- return {
- type = 'UNKNOWN',
- start = pos or 0,
- finish = pos or 0,
- err = err,
- }
-end
-
-grammar 'Comment' [[
-Comment <- LongComment / '--' ShortComment
-LongComment <- ('--[' {} {:eq: '='* :} {} '['
- {(!CommentClose .)*}
- (CommentClose {} / {} {}))
- -> LongComment
- / (
- {} '/*' {}
- (!'*/' .)*
- {} '*/' {}
- )
- -> CLongComment
-CommentClose <- ']' =eq ']'
-ShortComment <- (!%nl .)*
-]]
-
-grammar 'Sp' [[
-Sp <- (Comment / %nl / %s)*
-Sps <- (Comment / %nl / %s)+
-]]
-
-grammar 'Common' [[
-Word <- [a-zA-Z0-9_]
-Cut <- !Word
-X16 <- [a-fA-F0-9]
-Rest <- (!%nl .)*
-
-AND <- Sp {'and'} Cut
-BREAK <- Sp 'break' Cut
-DO <- Sp 'do' Cut
- / Sp ({} 'then' Cut {}) -> ErrDo
-ELSE <- Sp 'else' Cut
-ELSEIF <- Sp 'elseif' Cut
-END <- Sp 'end' Cut
-FALSE <- Sp 'false' Cut
-FOR <- Sp 'for' Cut
-FUNCTION <- Sp 'function' Cut
-GOTO <- Sp 'goto' Cut
-IF <- Sp 'if' Cut
-IN <- Sp 'in' Cut
-LOCAL <- Sp 'local' Cut
-NIL <- Sp 'nil' Cut
-NOT <- Sp 'not' Cut
-OR <- Sp {'or'} Cut
-REPEAT <- Sp 'repeat' Cut
-RETURN <- Sp 'return' Cut
-THEN <- Sp 'then' Cut
- / Sp ({} 'do' Cut {}) -> ErrThen
-TRUE <- Sp 'true' Cut
-UNTIL <- Sp 'until' Cut
-WHILE <- Sp 'while' Cut
-
-Esc <- '\' -> ''
- EChar
-EChar <- 'a' -> ea
- / 'b' -> eb
- / 'f' -> ef
- / 'n' -> en
- / 'r' -> er
- / 't' -> et
- / 'v' -> ev
- / '\'
- / '"'
- / "'"
- / %nl
- / ('z' (%nl / %s)*) -> ''
- / ({} 'x' {X16 X16}) -> Char16
- / ([0-9] [0-9]? [0-9]?) -> Char10
- / ('u{' {} {Word*} '}') -> CharUtf8
- -- 错误处理
- / 'x' {} -> MissEscX
- / 'u' !'{' {} -> MissTL
- / 'u{' Word* !'}' {} -> MissTR
- / {} -> ErrEsc
-
-BOR <- Sp {'|'}
-BXOR <- Sp {'~'} !'='
-BAND <- Sp {'&'}
-Bshift <- Sp {BshiftList}
-BshiftList <- '<<'
- / '>>'
-Concat <- Sp {'..'}
-Adds <- Sp {AddsList}
-AddsList <- '+'
- / '-'
-Muls <- Sp {MulsList}
-MulsList <- '*'
- / '//'
- / '/'
- / '%'
-Unary <- Sp {} {UnaryList}
-UnaryList <- NOT
- / '#'
- / '-'
- / '~' !'='
-POWER <- Sp {'^'}
-
-BinaryOp <- Sp {} {'or'} Cut
- / Sp {} {'and'} Cut
- / Sp {} {'<=' / '>=' / '<'!'<' / '>'!'>' / '~=' / '=='}
- / Sp {} ({} '=' {}) -> ErrEQ
- / Sp {} ({} '!=' {}) -> ErrUEQ
- / Sp {} {'|'}
- / Sp {} {'~'}
- / Sp {} {'&'}
- / Sp {} {'<<' / '>>'}
- / Sp {} {'..'} !'.'
- / Sp {} {'+' / '-'}
- / Sp {} {'*' / '//' / '/' / '%'}
- / Sp {} {'^'}
-UnaryOp <- Sp {} {'not' Cut / '#' / '~' !'=' / '-' !'-'}
-
-PL <- Sp '('
-PR <- Sp ')'
-BL <- Sp '[' !'[' !'='
-BR <- Sp ']'
-TL <- Sp '{'
-TR <- Sp '}'
-COMMA <- Sp ','
-SEMICOLON <- Sp ';'
-DOTS <- Sp ({} '...') -> DOTS
-DOT <- Sp ({} '.' !'.') -> DOT
-COLON <- Sp ({} ':' !':') -> COLON
-LABEL <- Sp '::'
-ASSIGN <- Sp '=' !'='
-AssignOrEQ <- Sp ({} '==' {}) -> ErrAssign
- / Sp '='
-
-Nothing <- {} -> Nothing
-
-DirtyBR <- BR {} / {} -> MissBR
-DirtyTR <- TR {} / {} -> MissTR
-DirtyPR <- PR {} / {} -> DirtyPR
-DirtyLabel <- LABEL / {} -> MissLabel
-NeedPR <- PR / {} -> MissPR
-NeedEnd <- END / {} -> MissEnd
-NeedDo <- DO / {} -> MissDo
-NeedAssign <- ASSIGN / {} -> MissAssign
-NeedComma <- COMMA / {} -> MissComma
-NeedIn <- IN / {} -> MissIn
-NeedUntil <- UNTIL / {} -> MissUntil
-]]
-
-grammar 'Nil' [[
-Nil <- Sp ({} -> Nil) NIL
-]]
-
-grammar 'Boolean' [[
-Boolean <- Sp ({} -> True) TRUE
- / Sp ({} -> False) FALSE
-]]
-
-grammar 'String' [[
-String <- Sp ({} StringDef {})
- -> String
-StringDef <- {'"'}
- {~(Esc / !%nl !'"' .)*~} -> 1
- ('"' / {} -> MissQuote1)
- / {"'"}
- {~(Esc / !%nl !"'" .)*~} -> 1
- ("'" / {} -> MissQuote2)
- / ('[' {} {:eq: '='* :} {} '[' %nl?
- {(!StringClose .)*} -> 1
- (StringClose / {}))
- -> LongString
-StringClose <- ']' =eq ']'
-]]
-
-grammar 'Number' [[
-Number <- Sp ({} {NumberDef} {}) -> Number
- NumberSuffix?
- ErrNumber?
-NumberDef <- Number16 / Number10
-NumberSuffix<- ({} {[uU]? [lL] [lL]}) -> FFINumber
- / ({} {[iI]}) -> ImaginaryNumber
-ErrNumber <- ({} {([0-9a-zA-Z] / '.')+}) -> UnknownSymbol
-
-Number10 <- Float10 Float10Exp?
- / Integer10 Float10? Float10Exp?
-Integer10 <- [0-9]+ ('.' [0-9]*)?
-Float10 <- '.' [0-9]+
-Float10Exp <- [eE] [+-]? [0-9]+
- / ({} [eE] [+-]? {}) -> MissExponent
-
-Number16 <- '0' [xX] Float16 Float16Exp?
- / '0' [xX] Integer16 Float16? Float16Exp?
-Integer16 <- X16+ ('.' X16*)?
- / ({} {Word*}) -> MustX16
-Float16 <- '.' X16+
- / '.' ({} {Word*}) -> MustX16
-Float16Exp <- [pP] [+-]? [0-9]+
- / ({} [pP] [+-]? {}) -> MissExponent
-]]
-
-grammar 'Name' [[
-Name <- Sp ({} NameBody {})
- -> Name
-NameBody <- {[a-zA-Z_] [a-zA-Z0-9_]*}
-FreeName <- Sp ({} {NameBody=>NotReserved} {})
- -> Name
-MustName <- Name / DirtyName
-DirtyName <- {} -> DirtyName
-]]
-
-grammar 'Exp' [[
-Exp <- (UnUnit (BinaryOp (UnUnit / {} -> DirtyExp))*)
- -> Exp
-UnUnit <- ExpUnit
- / UnaryOp+ (ExpUnit / {} -> DirtyExp)
-ExpUnit <- Nil
- / Boolean
- / String
- / Number
- / DOTS -> DotsAsExp
- / Table
- / Function
- / Simple
-
-Simple <- (Prefix (Sp Suffix)*)
- -> Simple
-Prefix <- Sp ({} PL DirtyExp DirtyPR)
- -> Prefix
- / FreeName
-Index <- ({} BL DirtyExp DirtyBR) -> Index
-Suffix <- DOT Name / DOT {} -> MissField
- / Method (!(Sp CallStart) {} -> MissPL)?
- / ({} Table {}) -> Call
- / ({} String {}) -> Call
- / Index
- / ({} PL CallArgList DirtyPR) -> Call
-Method <- COLON Name / COLON {} -> MissMethod
-CallStart <- PL
- / TL
- / '"'
- / "'"
- / '[' '='* '['
-
-DirtyExp <- Exp
- / {} -> DirtyExp
-MaybeExp <- Exp / MissExp
-MissExp <- {} -> MissExp
-ExpList <- Sp (MaybeExp (COMMA (MaybeExp))*)
- -> List
-MustExpList <- Sp (Exp (COMMA (MaybeExp))*)
- -> List
-CallArgList <- Sp ({} (COMMA {} / Exp)+ {})
- -> CallArgList
- / %nil
-NameList <- (MustName (COMMA MustName)*)
- -> List
-
-ArgList <- (DOTS -> DotsAsArg / Name / Sp {} COMMA)*
- -> ArgList
-
-Table <- Sp ({} TL TableFields? DirtyTR)
- -> Table
-TableFields <- (Emmy / TableSep {} / TableField)+
-TableSep <- COMMA / SEMICOLON
-TableField <- NewIndex / NewField / Exp
-NewIndex <- Sp (Index NeedAssign DirtyExp)
- -> NewIndex
-NewField <- (MustName ASSIGN DirtyExp)
- -> NewField
-
-Function <- Sp ({} FunctionBody {})
- -> Function
-FuncArg <- PL {} ArgList {} NeedPR
- / {} {} -> MissPL Nothing {}
-FunctionBody<- FUNCTION BlockStart FuncArg
- (Emmy / !END Action)*
- BlockEnd
- NeedEnd
-
-BlockStart <- {} -> BlockStart
-BlockEnd <- {} -> BlockEnd
-
--- 纯占位,修改了 `relabel.lua` 使重复定义不抛错
-Action <- !END .
-Set <- END
-Emmy <- '---@'
-]]
-
-grammar 'Action' [[
-Action <- Sp (CrtAction / UnkAction)
-CrtAction <- Semicolon
- / Do
- / Break
- / Return
- / Label
- / GoTo
- / If
- / For
- / While
- / Repeat
- / NamedFunction
- / LocalFunction
- / Local
- / Set
- / Call
- / ExpInAction
-UnkAction <- ({} {Word+})
- -> UnknownAction
- / ({} '//' {} (LongComment / ShortComment))
- -> CCommentPrefix
- / ({} {. (!Sps !CrtAction .)*})
- -> UnknownAction
-ExpInAction <- Sp ({} Exp {})
- -> ExpInAction
-
-Semicolon <- SEMICOLON
- -> Skip
-SimpleList <- (Simple (COMMA Simple)*)
- -> List
-
-Do <- Sp ({} 'do' Cut DoBody NeedEnd {})
- -> Do
-DoBody <- (Emmy / !END Action)*
- -> DoBody
-
-Break <- BREAK ({} Semicolon* AfterBreak?)
- -> Break
-AfterBreak <- Sp !END !UNTIL !ELSEIF !ELSE Action
-BreakStart <- {} -> BreakStart
-BreakEnd <- {} -> BreakEnd
-
-Return <- (ReturnBody Semicolon* AfterReturn?)
- -> AfterReturn
-ReturnBody <- Sp ({} RETURN MustExpList? {})
- -> Return
-AfterReturn <- Sp !END !UNTIL !ELSEIF !ELSE Action
-
-Label <- Sp ({} LABEL MustName DirtyLabel {}) -> Label
-
-GoTo <- Sp ({} GOTO MustName {}) -> GoTo
-
-If <- Sp ({} IfBody {})
- -> If
-IfHead <- (IfPart -> IfBlock)
- / ({} ElseIfPart -> ElseIfBlock)
- -> MissIf
- / ({} ElsePart -> ElseBlock)
- -> MissIf
-IfBody <- IfHead
- (ElseIfPart -> ElseIfBlock)*
- (ElsePart -> ElseBlock)?
- NeedEnd
-IfPart <- IF DirtyExp THEN
- {} (Emmy / !ELSEIF !ELSE !END Action)* {}
- / IF DirtyExp {}->MissThen
- {} {}
-ElseIfPart <- ELSEIF DirtyExp THEN
- {} (Emmy / !ELSE !ELSEIF !END Action)* {}
- / ELSEIF DirtyExp {}->MissThen
- {} {}
-ElsePart <- ELSE
- {} (Emmy / !END Action)* {}
-
-For <- Loop / In
- / FOR
-
-Loop <- Sp ({} LoopBody {})
- -> Loop
-LoopBody <- FOR LoopStart LoopFinish LoopStep NeedDo
- BreakStart
- (Emmy / !END Action)*
- BreakEnd
- NeedEnd
-LoopStart <- MustName AssignOrEQ DirtyExp
-LoopFinish <- NeedComma DirtyExp
-LoopStep <- COMMA DirtyExp
- / NeedComma Exp
- / Nothing
-
-In <- Sp ({} InBody {})
- -> In
-InBody <- FOR InNameList NeedIn ExpList NeedDo
- BreakStart
- (Emmy / !END Action)*
- BreakEnd
- NeedEnd
-InNameList <- &IN DirtyName
- / NameList
-
-While <- Sp ({} WhileBody {})
- -> While
-WhileBody <- WHILE DirtyExp NeedDo
- BreakStart
- (Emmy / !END Action)*
- BreakEnd
- NeedEnd
-
-Repeat <- Sp ({} RepeatBody {})
- -> Repeat
-RepeatBody <- REPEAT
- BreakStart
- (Emmy / !UNTIL Action)*
- BreakEnd
- NeedUntil DirtyExp
-
-LocalTag <- (Sp '<' Sp MustName Sp LocalTagEnd)*
- -> LocalTag
-LocalTagEnd <- '>' / {} -> MissGT
-Local <- (LOCAL LocalNameList (AssignOrEQ ExpList)?)
- -> Local
-Set <- (SimpleList AssignOrEQ ExpList?)
- -> Set
-LocalNameList
- <- (LocalName (COMMA LocalName)*)
- -> List
-LocalName <- (MustName LocalTag)
- -> LocalName
-
-Call <- Simple
- -> SimpleCall
-
-LocalFunction
- <- Sp ({} LOCAL FunctionNamedBody {})
- -> LocalFunction
-
-NamedFunction
- <- Sp ({} FunctionNamedBody {})
- -> NamedFunction
-FunctionNamedBody
- <- FUNCTION FuncName BlockStart FuncArg
- (Emmy / !END Action)*
- BlockEnd
- NeedEnd
-FuncName <- (MustName (DOT MustName)* FuncMethod?)
- -> Simple
-FuncMethod <- COLON Name / COLON {} -> MissMethod
-
--- 占位
-Emmy <- '---@'
-]]
-
-grammar 'Emmy' [[
-Emmy <- EmmyAction
- / EmmyComments
-EmmyAction <- EmmySp '---' %s* '@' EmmyBody ShortComment
-EmmySp <- (!'---' Comment / %s / %nl)*
-EmmyComments <- EmmyComment+
- -> EmmyComment
-EmmyComment <- EmmySp '---' %s* !'@' {(!%nl .)*}
-EmmyBody <- 'class' %s+ EmmyClass -> EmmyClass
- / 'type' %s+ EmmyType -> EmmyType
- / 'alias' %s+ EmmyAlias -> EmmyAlias
- / 'param' %s+ EmmyParam -> EmmyParam
- / 'return' %s+ EmmyReturn -> EmmyReturn
- / 'field' %s+ EmmyField -> EmmyField
- / 'generic' %s+ EmmyGeneric -> EmmyGeneric
- / 'vararg' %s+ EmmyVararg -> EmmyVararg
- / 'language' %s+ EmmyLanguage -> EmmyLanguage
- / 'see' %s+ EmmySee -> EmmySee
- / 'overload' %s+ EmmyOverLoad -> EmmyOverLoad
- / EmmyIncomplete
-
-EmmyName <- ({} {[a-zA-Z_] [a-zA-Z0-9_.]*})
- -> EmmyName
-MustEmmyName <- EmmyName / DirtyEmmyName
-DirtyEmmyName <- {} -> DirtyEmmyName
-EmmyLongName <- ({} {(!%nl .)+})
- -> EmmyName
-EmmyIncomplete <- MustEmmyName
- -> EmmyIncomplete
-
-EmmyClass <- (MustEmmyName EmmyParentClass?)
-EmmyParentClass <- %s* {} ':' %s* MustEmmyName
-
-EmmyType <- EmmyFunctionType
- / EmmyTableType
- / EmmyArrayType
- / EmmyCommonType
-EmmyCommonType <- EmmyTypeNames
- -> EmmyCommonType
-EmmyTypeNames <- EmmyTypeName (%s* {} '|' %s* !String EmmyTypeName)*
-EmmyTypeName <- EmmyFunctionType
- / EmmyTableType
- / EmmyArrayType
- / MustEmmyName
-EmmyTypeEnum <- %s* (%nl %s* '---')? '|' EmmyEnum
- -> EmmyTypeEnum
-EmmyEnum <- %s* {'>'?} %s* String (EmmyEnumComment / (!%nl !'|' .)*)
-EmmyEnumComment <- %s* '#' %s* {(!%nl .)*}
-
-EmmyAlias <- MustEmmyName %s* EmmyType EmmyTypeEnum*
-
-EmmyParam <- MustEmmyName %s* EmmyType %s* EmmyOption %s* EmmyTypeEnum*
-EmmyOption <- Table?
- -> EmmyOption
-
-EmmyReturn <- {} %nil %nil {} Table -> EmmyOption
- / {} EmmyType (%s* EmmyName/%nil) {} EmmyOption
-
-EmmyField <- (EmmyFieldAccess MustEmmyName %s* EmmyType)
-EmmyFieldAccess <- ({'public'} Cut %s*)
- / ({'protected'} Cut %s*)
- / ({'private'} Cut %s*)
- / {} -> 'public'
-
-EmmyGeneric <- EmmyGenericBlock
- (%s* ',' %s* EmmyGenericBlock)*
-EmmyGenericBlock<- (MustEmmyName %s* (':' %s* EmmyType)?)
- -> EmmyGenericBlock
-
-EmmyVararg <- EmmyType
-
-EmmyLanguage <- MustEmmyName
-
-EmmyArrayType <- ({} MustEmmyName -> EmmyCommonType {} '[' DirtyBR)
- -> EmmyArrayType
- / ({} PL EmmyCommonType DirtyPR '[' DirtyBR)
- -> EmmyArrayType
-
-EmmyTableType <- ({} 'table' Cut '<' %s* EmmyType %s* ',' %s* EmmyType %s* '>' {})
- -> EmmyTableType
-
-EmmyFunctionType<- ({} 'fun' Cut %s* EmmyFunctionArgs %s* EmmyFunctionRtns {})
- -> EmmyFunctionType
-EmmyFunctionArgs<- ('(' %s* EmmyFunctionArg %s* (',' %s* EmmyFunctionArg %s*)* DirtyPR)
- -> EmmyFunctionArgs
- / '(' %nil DirtyPR -> None
- / %nil
-EmmyFunctionRtns<- (':' %s* EmmyType (%s* ',' %s* EmmyType)*)
- -> EmmyFunctionRtns
- / %nil
-EmmyFunctionArg <- MustEmmyName %s* ':' %s* EmmyType
-
-EmmySee <- {} MustEmmyName %s* '#' %s* MustEmmyName {}
-EmmyOverLoad <- EmmyFunctionType
-]]
-
-grammar 'Lua' [[
-Lua <- Head?
- (Emmy / Action)* -> Lua
- BlockEnd
- Sp
-Head <- '#' (!%nl .)*
-]]
-
-return function (self, lua, mode)
- local gram = compiled[mode] or compiled['Lua']
- local r, _, pos = gram:match(lua)
- if not r then
- local err = errorpos(pos)
- return nil, err
- end
-
- return r
-end
diff --git a/script/parser/init.lua b/script/parser/init.lua
deleted file mode 100644
index 30596dbe..00000000
--- a/script/parser/init.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-local api = {
- grammar = require 'parser.grammar',
- parse = require 'parser.parse',
- split = require 'parser.split',
- calcline = require 'parser.calcline',
- lines = require 'parser.lines',
-}
-
-return api
diff --git a/script/parser/lines.lua b/script/parser/lines.lua
deleted file mode 100644
index a5fe8116..00000000
--- a/script/parser/lines.lua
+++ /dev/null
@@ -1,190 +0,0 @@
-local m = require 'lpeglabel'
-
-local function utf8_len(buf, start, finish)
- local len, pos = utf8.len(buf, start, finish)
- if len then
- return len
- end
- return 1 + utf8_len(buf, start, pos-1) + utf8_len(buf, pos+1, finish)
-end
-
-local function Line(start, line, finish)
- line.start = start
- line.finish = finish - 1
- return line
-end
-
-local function Space(...)
- local line = {...}
- local sp = 0
- local tab = 0
- for i = 1, #line do
- if line[i] == ' ' then
- sp = sp + 1
- elseif line[i] == '\t' then
- tab = tab + 1
- end
- line[i] = nil
- end
- line.sp = sp
- line.tab = tab
- return line
-end
-
-local parser = m.P{
-'Lines',
-Lines = m.Ct(m.V'Line'^0 * m.V'LastLine'),
-Line = m.Cp() * m.V'Indent' * (1 - m.V'Nl')^0 * m.Cp() * m.V'Nl' / Line,
-LastLine= m.Cp() * m.V'Indent' * (1 - m.V'Nl')^0 * m.Cp() / Line,
-Nl = m.P'\r\n' + m.S'\r\n',
-Indent = m.C(m.S' \t')^0 / Space,
-}
-
-local mt = {}
-mt.__index = mt
-
-function mt:position(row, col, code)
- if row < 1 then
- return 1
- end
- code = code or self.code
- if row > #self then
- if code == 'utf8' then
- return utf8_len(self.buf) + 1
- else
- return #self.buf + 1
- end
- end
- local line = self[row]
- local next_line = self[row+1]
- local start = line.start
- local finish
- if next_line then
- finish = next_line.start - 1
- else
- finish = #self.buf + 1
- end
- local pos
- if code == 'utf8' then
- if start > finish then
- return finish
- end
- pos = utf8.offset(self.buf, col, start) or finish
- else
- pos = start + col - 1
- end
- if pos < start then
- pos = start
- elseif pos > finish then
- pos = finish
- end
- return pos
-end
-
-local function isCharByte(byte)
- if not byte then
- return false
- end
- -- [0-9]
- if byte >= 48 and byte <= 57 then
- return true
- end
- -- [A-Z]
- if byte >= 65 and byte <= 90 then
- return true
- end
- -- [a-z]
- if byte >= 97 and byte <= 122 then
- return true
- end
- -- <utf8>
- if byte >= 128 then
- return true
- end
- return false
-end
-
-function mt:positionAsChar(row, col, code)
- local pos = self:position(row, col, code)
- if isCharByte(self.buf:byte(pos, pos)) then
- return pos
- elseif isCharByte(self.buf:byte(pos+1, pos+1)) then
- return pos + 1
- end
- return pos
-end
-
-function mt:rowcol(pos, code)
- if pos < 1 then
- return 1, 1
- end
- code = code or self.code
- if pos >= #self.buf + 1 then
- local start = self[#self].start
- if code == 'utf8' then
- return #self, utf8_len(self.buf, start) + 1
- else
- return #self, #self.buf - start + 2
- end
- end
- local min = 1
- local max = #self
- for _ = 1, 100 do
- if max == min then
- local start = self[min].start
- if code == 'utf8' then
- return min, utf8_len(self.buf, start, pos)
- else
- return min, pos - start + 1
- end
- end
- local row = (max - min) // 2 + min
- local start = self[row].start
- if pos < start then
- max = row
- elseif pos > start then
- local next_start = self[row + 1].start
- if pos < next_start then
- if code == 'utf8' then
- return row, utf8_len(self.buf, start, pos)
- else
- return row, pos - start + 1
- end
- elseif pos > next_start then
- min = row + 1
- else
- return row + 1, 1
- end
- else
- return row, 1
- end
- end
- error('rowcol failed!')
-end
-
-function mt:line(i)
- local start, finish = self:range(i)
- return self.buf:sub(start, finish)
-end
-
-function mt:range(i)
- if i < 1 or i > #self then
- return 0, 0
- end
- return self[i].start, self[i].finish
-end
-
-function mt:set_code(code)
- self.code = code
-end
-
-return function (self, buf, code)
- local lines, err = parser:match(buf)
- if not lines then
- return nil, err
- end
- lines.buf = buf
- lines.code = code
-
- return setmetatable(lines, mt)
-end
diff --git a/script/parser/parse.lua b/script/parser/parse.lua
deleted file mode 100644
index 6ad79d9b..00000000
--- a/script/parser/parse.lua
+++ /dev/null
@@ -1,41 +0,0 @@
-local ast = require 'parser.ast'
-
-local Errs
-local State
-
-local function pushError(err)
- if err.finish < err.start then
- err.finish = err.start
- end
- local last = Errs[#Errs]
- if last then
- if last.start <= err.start and last.finish >= err.finish then
- return
- end
- end
- err.level = err.level or 'error'
- Errs[#Errs+1] = err
- return err
-end
-
-return function (self, lua, mode, version)
- Errs = {}
- State= {
- Break = 0,
- Label = {{}},
- Dots = {true},
- Version = version,
- Comments = {},
- Lua = lua,
- }
- ast.init(State, Errs)
- local suc, res, err = xpcall(self.grammar, debug.traceback, self, lua, mode)
- if not suc then
- return nil, res
- end
- if not res then
- pushError(err)
- return nil, Errs
- end
- return res, Errs, State.Comments
-end
diff --git a/script/parser/relabel.lua b/script/parser/relabel.lua
deleted file mode 100644
index ac902403..00000000
--- a/script/parser/relabel.lua
+++ /dev/null
@@ -1,361 +0,0 @@
--- $Id: re.lua,v 1.44 2013/03/26 20:11:40 roberto Exp $
-
--- imported functions and modules
-local tonumber, type, print, error = tonumber, type, print, error
-local pcall = pcall
-local setmetatable = setmetatable
-local tinsert, concat = table.insert, table.concat
-local rep = string.rep
-local m = require"lpeglabel"
-
--- 'm' will be used to parse expressions, and 'mm' will be used to
--- create expressions; that is, 're' runs on 'm', creating patterns
--- on 'mm'
-local mm = m
-
--- pattern's metatable
-local mt = getmetatable(mm.P(0))
-
-
-
--- No more global accesses after this point
-_ENV = nil
-
-
-local any = m.P(1)
-local dummy = mm.P(false)
-
-
-local errinfo = {
- NoPatt = "no pattern found",
- ExtraChars = "unexpected characters after the pattern",
-
- ExpPatt1 = "expected a pattern after '/'",
-
- ExpPatt2 = "expected a pattern after '&'",
- ExpPatt3 = "expected a pattern after '!'",
-
- ExpPatt4 = "expected a pattern after '('",
- ExpPatt5 = "expected a pattern after ':'",
- ExpPatt6 = "expected a pattern after '{~'",
- ExpPatt7 = "expected a pattern after '{|'",
-
- ExpPatt8 = "expected a pattern after '<-'",
-
- ExpPattOrClose = "expected a pattern or closing '}' after '{'",
-
- ExpNumName = "expected a number, '+', '-' or a name (no space) after '^'",
- ExpCap = "expected a string, number, '{}' or name after '->'",
-
- ExpName1 = "expected the name of a rule after '=>'",
- ExpName2 = "expected the name of a rule after '=' (no space)",
- ExpName3 = "expected the name of a rule after '<' (no space)",
-
- ExpLab1 = "expected a label after '{'",
-
- ExpNameOrLab = "expected a name or label after '%' (no space)",
-
- ExpItem = "expected at least one item after '[' or '^'",
-
- MisClose1 = "missing closing ')'",
- MisClose2 = "missing closing ':}'",
- MisClose3 = "missing closing '~}'",
- MisClose4 = "missing closing '|}'",
- MisClose5 = "missing closing '}'", -- for the captures
-
- MisClose6 = "missing closing '>'",
- MisClose7 = "missing closing '}'", -- for the labels
-
- MisClose8 = "missing closing ']'",
-
- MisTerm1 = "missing terminating single quote",
- MisTerm2 = "missing terminating double quote",
-}
-
-local function expect (pattern, label)
- return pattern + m.T(label)
-end
-
-
--- Pre-defined names
-local Predef = { nl = m.P"\n" }
-
-
-local mem
-local fmem
-local gmem
-
-
-local function updatelocale ()
- mm.locale(Predef)
- Predef.a = Predef.alpha
- Predef.c = Predef.cntrl
- Predef.d = Predef.digit
- Predef.g = Predef.graph
- Predef.l = Predef.lower
- Predef.p = Predef.punct
- Predef.s = Predef.space
- Predef.u = Predef.upper
- Predef.w = Predef.alnum
- Predef.x = Predef.xdigit
- Predef.A = any - Predef.a
- Predef.C = any - Predef.c
- Predef.D = any - Predef.d
- Predef.G = any - Predef.g
- Predef.L = any - Predef.l
- Predef.P = any - Predef.p
- Predef.S = any - Predef.s
- Predef.U = any - Predef.u
- Predef.W = any - Predef.w
- Predef.X = any - Predef.x
- mem = {} -- restart memoization
- fmem = {}
- gmem = {}
- local mt = {__mode = "v"}
- setmetatable(mem, mt)
- setmetatable(fmem, mt)
- setmetatable(gmem, mt)
-end
-
-
-updatelocale()
-
-
-
-local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
-
-
-local function getdef (id, defs)
- local c = defs and defs[id]
- if not c then
- error("undefined name: " .. id)
- end
- return c
-end
-
-
-local function mult (p, n)
- local np = mm.P(true)
- while n >= 1 do
- if n%2 >= 1 then np = np * p end
- p = p * p
- n = n/2
- end
- return np
-end
-
-local function equalcap (s, i, c)
- if type(c) ~= "string" then return nil end
- local e = #c + i
- if s:sub(i, e - 1) == c then return e else return nil end
-end
-
-
-local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
-
-local name = m.C(m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0)
-
-local arrow = S * "<-"
-
--- a defined name only have meaning in a given environment
-local Def = name * m.Carg(1)
-
-local num = m.C(m.R"09"^1) * S / tonumber
-
-local String = "'" * m.C((any - "'" - m.P"\n")^0) * expect("'", "MisTerm1")
- + '"' * m.C((any - '"' - m.P"\n")^0) * expect('"', "MisTerm2")
-
-
-local defined = "%" * Def / function (c,Defs)
- local cat = Defs and Defs[c] or Predef[c]
- if not cat then
- error("name '" .. c .. "' undefined")
- end
- return cat
-end
-
-local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R
-
-local item = defined + Range + m.C(any - m.P"\n")
-
-local Class =
- "["
- * (m.C(m.P"^"^-1)) -- optional complement symbol
- * m.Cf(expect(item, "ExpItem") * (item - "]")^0, mt.__add)
- / function (c, p) return c == "^" and any - p or p end
- * expect("]", "MisClose8")
-
-local function adddef (t, k, exp)
- if t[k] then
- -- TODO 改了一下这里的代码,重复定义不会抛错
- --error("'"..k.."' already defined as a rule")
- else
- t[k] = exp
- end
- return t
-end
-
-local function firstdef (n, r) return adddef({n}, n, r) end
-
-
-local function NT (n, b)
- if not b then
- error("rule '"..n.."' used outside a grammar")
- else return mm.V(n)
- end
-end
-
-
-local exp = m.P{ "Exp",
- Exp = S * ( m.V"Grammar"
- + m.Cf(m.V"Seq" * (S * "/" * expect(S * m.V"Seq", "ExpPatt1"))^0, mt.__add) );
- Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix" * (S * m.V"Prefix")^0, mt.__mul);
- Prefix = "&" * expect(S * m.V"Prefix", "ExpPatt2") / mt.__len
- + "!" * expect(S * m.V"Prefix", "ExpPatt3") / mt.__unm
- + m.V"Suffix";
- Suffix = m.Cf(m.V"Primary" *
- ( S * ( m.P"+" * m.Cc(1, mt.__pow)
- + m.P"*" * m.Cc(0, mt.__pow)
- + m.P"?" * m.Cc(-1, mt.__pow)
- + "^" * expect( m.Cg(num * m.Cc(mult))
- + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow)
- + name * m.Cc"lab"
- ),
- "ExpNumName")
- + "->" * expect(S * ( m.Cg((String + num) * m.Cc(mt.__div))
- + m.P"{}" * m.Cc(nil, m.Ct)
- + m.Cg(Def / getdef * m.Cc(mt.__div))
- ),
- "ExpCap")
- + "=>" * expect(S * m.Cg(Def / getdef * m.Cc(m.Cmt)),
- "ExpName1")
- )
- )^0, function (a,b,f) if f == "lab" then return a + mm.T(b) else return f(a,b) end end );
- Primary = "(" * expect(m.V"Exp", "ExpPatt4") * expect(S * ")", "MisClose1")
- + String / mm.P
- + Class
- + defined
- + "%" * expect(m.P"{", "ExpNameOrLab")
- * expect(S * m.V"Label", "ExpLab1")
- * expect(S * "}", "MisClose7") / mm.T
- + "{:" * (name * ":" + m.Cc(nil)) * expect(m.V"Exp", "ExpPatt5")
- * expect(S * ":}", "MisClose2")
- / function (n, p) return mm.Cg(p, n) end
- + "=" * expect(name, "ExpName2")
- / function (n) return mm.Cmt(mm.Cb(n), equalcap) end
- + m.P"{}" / mm.Cp
- + "{~" * expect(m.V"Exp", "ExpPatt6")
- * expect(S * "~}", "MisClose3") / mm.Cs
- + "{|" * expect(m.V"Exp", "ExpPatt7")
- * expect(S * "|}", "MisClose4") / mm.Ct
- + "{" * expect(m.V"Exp", "ExpPattOrClose")
- * expect(S * "}", "MisClose5") / mm.C
- + m.P"." * m.Cc(any)
- + (name * -arrow + "<" * expect(name, "ExpName3")
- * expect(">", "MisClose6")) * m.Cb("G") / NT;
- Label = num + name;
- Definition = name * arrow * expect(m.V"Exp", "ExpPatt8");
- Grammar = m.Cg(m.Cc(true), "G")
- * m.Cf(m.V"Definition" / firstdef * (S * m.Cg(m.V"Definition"))^0,
- adddef) / mm.P;
-}
-
-local pattern = S * m.Cg(m.Cc(false), "G") * expect(exp, "NoPatt") / mm.P
- * S * expect(-any, "ExtraChars")
-
-local function lineno (s, i)
- if i == 1 then return 1, 1 end
- local adjustment = 0
- -- report the current line if at end of line, not the next
- if s:sub(i,i) == '\n' then
- i = i-1
- adjustment = 1
- end
- local rest, num = s:sub(1,i):gsub("[^\n]*\n", "")
- local r = #rest
- return 1 + num, (r ~= 0 and r or 1) + adjustment
-end
-
-local function calcline (s, i)
- if i == 1 then return 1, 1 end
- local rest, line = s:sub(1,i):gsub("[^\n]*\n", "")
- local col = #rest
- return 1 + line, col ~= 0 and col or 1
-end
-
-
-local function splitlines(str)
- local t = {}
- local function helper(line) tinsert(t, line) return "" end
- helper((str:gsub("(.-)\r?\n", helper)))
- return t
-end
-
-local function compile (p, defs)
- if mm.type(p) == "pattern" then return p end -- already compiled
- p = p .. " " -- for better reporting of column numbers in errors when at EOF
- local ok, cp, label, poserr = pcall(function() return pattern:match(p, 1, defs) end)
- if not ok and cp then
- if type(cp) == "string" then
- cp = cp:gsub("^[^:]+:[^:]+: ", "")
- end
- error(cp, 3)
- end
- if not cp then
- local lines = splitlines(p)
- local line, col = lineno(p, poserr)
- local err = {}
- tinsert(err, "L" .. line .. ":C" .. col .. ": " .. errinfo[label])
- tinsert(err, lines[line])
- tinsert(err, rep(" ", col-1) .. "^")
- error("syntax error(s) in pattern\n" .. concat(err, "\n"), 3)
- end
- return cp
-end
-
-local function match (s, p, i)
- local cp = mem[p]
- if not cp then
- cp = compile(p)
- mem[p] = cp
- end
- return cp:match(s, i or 1)
-end
-
-local function find (s, p, i)
- local cp = fmem[p]
- if not cp then
- cp = compile(p) / 0
- cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) }
- fmem[p] = cp
- end
- local i, e = cp:match(s, i or 1)
- if i then return i, e - 1
- else return i
- end
-end
-
-local function gsub (s, p, rep)
- local g = gmem[p] or {} -- ensure gmem[p] is not collected while here
- gmem[p] = g
- local cp = g[rep]
- if not cp then
- cp = compile(p)
- cp = mm.Cs((cp / rep + 1)^0)
- g[rep] = cp
- end
- return cp:match(s)
-end
-
-
--- exported names
-local re = {
- compile = compile,
- match = match,
- find = find,
- gsub = gsub,
- updatelocale = updatelocale,
- calcline = calcline
-}
-
-return re
diff --git a/script/parser/split.lua b/script/parser/split.lua
deleted file mode 100644
index 6ce4a4e7..00000000
--- a/script/parser/split.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-local m = require 'lpeglabel'
-
-local NL = m.P'\r\n' + m.S'\r\n'
-local LINE = m.C(1 - NL)
-
-return function (str)
- local MATCH = m.Ct((LINE * NL)^0 * LINE)
- return MATCH:match(str)
-end