diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:55:41 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:55:41 +0800 |
commit | c63b2e404d8d2bb984afe3678a5ba2b2836380cc (patch) | |
tree | a70661effacc7a29caa8d49583673ac4be2faaf5 /script/parser | |
parent | 85c5a4210e4447422cd5677369ae740ed65725a0 (diff) | |
download | lua-language-server-c63b2e404d8d2bb984afe3678a5ba2b2836380cc.zip |
remove the old version
Diffstat (limited to 'script/parser')
-rw-r--r-- | script/parser/ast.lua | 1913 | ||||
-rw-r--r-- | script/parser/calcline.lua | 93 | ||||
-rw-r--r-- | script/parser/grammar.lua | 630 | ||||
-rw-r--r-- | script/parser/init.lua | 9 | ||||
-rw-r--r-- | script/parser/lines.lua | 190 | ||||
-rw-r--r-- | script/parser/parse.lua | 41 | ||||
-rw-r--r-- | script/parser/relabel.lua | 361 | ||||
-rw-r--r-- | script/parser/split.lua | 9 |
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 |