diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-09-23 21:16:08 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-09-23 21:16:08 +0800 |
commit | 4dec306912bd95049e038c110ec4356b67630d60 (patch) | |
tree | 8ba4a14fc4446c2861207f5413675e914f5454e1 /server-beta | |
parent | d411d485cba488cbab4e6a920cc8adca76e00712 (diff) | |
download | lua-language-server-4dec306912bd95049e038c110ec4356b67630d60.zip |
更新 LuaParser
Diffstat (limited to 'server-beta')
-rw-r--r-- | server-beta/debugger.lua | 2 | ||||
-rw-r--r-- | server-beta/src/parser/ast.lua | 266 | ||||
-rw-r--r-- | server-beta/src/parser/grammar.lua | 7 |
3 files changed, 114 insertions, 161 deletions
diff --git a/server-beta/debugger.lua b/server-beta/debugger.lua index 79b2931d..cc304209 100644 --- a/server-beta/debugger.lua +++ b/server-beta/debugger.lua @@ -44,7 +44,7 @@ local function tryDebugger() local addr = "127.0.0.1:" .. port local dbg = loadfile(entry)('windows', root) dbg:start(addr) - dbg:wait() + --dbg:wait() log.debug('Debugger startup, listen port:', port) log.debug('Debugger args:', addr, root, path, cpath) end diff --git a/server-beta/src/parser/ast.lua b/server-beta/src/parser/ast.lua index 3ee264c1..cacb0e13 100644 --- a/server-beta/src/parser/ast.lua +++ b/server-beta/src/parser/ast.lua @@ -6,6 +6,8 @@ local utf8Char = utf8.char local tableUnpack = table.unpack local mathType = math.type local tableRemove = table.remove +local pairs = pairs +local tableSort = table.sort _ENV = nil @@ -67,98 +69,6 @@ local function checkOpVersion(op) } 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+1, -1 do - local op = list[i] - local opType = op.type - if info[opType] then - local e1 = expSplit(list, start, i-1, 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) - 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+1, finish-1 do - local op = list[i] - local opType = op.type - if info[opType] then - local e1 = expSplit(list, start, i-1, 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) - 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] - local opType = op.type - if info[opType] then - local e1 = expSplit(list, start+1, finish, level) - if e1 then - checkOpVersion(op) - return { - type = 'unary', - op = op, - start = op.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 @@ -274,68 +184,42 @@ local function packList(start, list, finish) return list 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 BinaryLevel = { + ['or'] = 1, + ['and'] = 2, + ['<='] = 3, + ['>='] = 3, + ['<'] = 3, + ['>'] = 3, + ['~='] = 3, + ['=='] = 3, + ['|'] = 4, + ['~'] = 5, + ['&'] = 6, + ['<<'] = 7, + ['>>'] = 7, + ['..'] = 8, + ['+'] = 9, + ['-'] = 9, + ['*'] = 10, + ['//'] = 10, + ['/'] = 10, + ['%'] = 10, + ['^'] = 11, +} + +local BinaryForward = { + [01] = true, + [02] = true, + [03] = true, + [04] = true, + [05] = true, + [06] = true, + [07] = true, + [08] = false, + [09] = true, + [10] = true, + [11] = false, } local Defs = { @@ -737,12 +621,80 @@ local Defs = { finish = start + #op - 1, } end, - Exp = function (first, ...) + Unary = function (first, ...) if not ... then - return first + return nil end local list = {first, ...} - return expSplit(list, 1, #list, 1) + local e = list[#list] + for i = #list - 1, 1, -1 do + local op = list[i] + checkOpVersion(op) + e = { + type = 'unary', + op = op, + start = op.start, + finish = e.finish, + [1] = e, + } + end + return e + end, + Binary = function (first, op, second, ...) + if not op then + return first + end + if not ... then + checkOpVersion(op) + return { + type = 'binary', + op = op, + start = first.start, + finish = second.finish, + [1] = first, + [2] = second, + } + end + local list = {first, op, second, ...} + local ops = {} + for i = 2, #list, 2 do + ops[#ops+1] = i + end + tableSort(ops, function (a, b) + local op1 = list[a] + local op2 = list[b] + local lv1 = BinaryLevel[op1.type] + local lv2 = BinaryLevel[op2.type] + if lv1 == lv2 then + local forward = BinaryForward[lv1] + if forward then + return op1.start > op2.start + else + return op1.start < op2.start + end + else + return lv1 < lv2 + end + end) + for i = #ops, 1, -1 do + local n = ops[i] + local op = list[n] + local left = list[n-1] + local right = list[n+1] + local exp = { + type = 'binary', + op = op, + start = left.start, + finish = right.finish, + [1] = left, + [2] = right, + } + list[n-1] = exp + list[n+1] = exp + checkOpVersion(op) + end + local final = ops[1] + return list[final-1] end, Paren = function (start, exp, finish) if exp and exp.type == 'paren' then diff --git a/server-beta/src/parser/grammar.lua b/server-beta/src/parser/grammar.lua index 8c491c64..944f34ea 100644 --- a/server-beta/src/parser/grammar.lua +++ b/server-beta/src/parser/grammar.lua @@ -295,10 +295,11 @@ DirtyName <- {} -> DirtyName ]] grammar 'Exp' [[ -Exp <- (UnUnit (BinaryOp (UnUnit / {} -> MissExp))*) - -> Exp +Exp <- (UnUnit (BinaryOp UnUnit / BinaryOp->None MissExp)*) + -> Binary UnUnit <- ExpUnit - / UnaryOp+ (ExpUnit / {} -> DirtyExp) + / (UnaryOp+ (ExpUnit / MissExp)) + -> Unary ExpUnit <- Nil / Boolean / String |