diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/parser/ast.lua | 199 | ||||
-rw-r--r-- | server/src/parser/grammar.lua | 51 |
2 files changed, 182 insertions, 68 deletions
diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua index 5efa9611..623c68fc 100644 --- a/server/src/parser/ast.lua +++ b/server/src/parser/ast.lua @@ -5,6 +5,7 @@ local type = type local Errs local State +local Defs local function pushError(err) if err.finish < err.start then err.finish = err.start @@ -44,7 +45,157 @@ local RESERVED = { ['while'] = true, } -local defs = { +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 + e2 = Defs.DirtyExp(#op + list[i-1]) + end + 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 + e2 = Defs.DirtyExp(#op + list[i-1]) + end + 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 + return { + type = 'unary', + op = op, + start = list[start], + finish = e1.finish, + [1] = e1, + } + end + end + return expSplit(list, start, finish, level+1) +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, + }, +} + +Defs = { Nil = function (pos) return { type = 'nil', @@ -201,6 +352,13 @@ local defs = { return first end 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) return exp end, @@ -234,43 +392,6 @@ local defs = { } return obj end, - Binary = function (...) - local e1, op = ... - if not op then - return e1 - end - local args = {...} - local e1 = args[1] - local e2 - for i = 2, #args, 2 do - op, e2 = args[i], args[i+1] - e1 = { - type = 'binary', - op = op, - start = e1.start, - finish = e2.finish, - [1] = e1, - [2] = e2, - } - end - return e1 - end, - Unary = function (...) - local args = {...} - local e1 = args[#args] - for i = #args - 1, 1, -2 do - local start = args[i-1] - local op = args[i] - e1 = { - type = 'unary', - op = op, - start = start, - finish = e1.finish, - [1] = e1, - } - end - return e1 - end, DOTS = function (start) return { type = '...', @@ -1041,7 +1162,7 @@ return function (self, lua, mode) Break = 0, Label = {{}}, } - local suc, res, err = pcall(self.grammar, lua, mode, defs) + local suc, res, err = pcall(self.grammar, lua, mode, Defs) if not suc then return nil, res end diff --git a/server/src/parser/grammar.lua b/server/src/parser/grammar.lua index f8b619b8..1843bd04 100644 --- a/server/src/parser/grammar.lua +++ b/server/src/parser/grammar.lua @@ -183,6 +183,19 @@ UnaryList <- NOT / '~' !'=' POWER <- Sp {'^'} +Op <- {} {'or'} Cut + / {} {'and'} Cut + / {} {'<=' / '>=' / '<'!'<' / '>'!'>' / '~=' / '=='} + / {} {'|'} + / {} {'~'} + / {} {'&'} + / {} {'<<' / '>>'} + / {} {'..'} !'.' + / {} {'+' / '-'} + / {} {'*' / '//' / '/' / '%'} + / {} {'not' Cut / '#'} + / {} {'^'} + PL <- Sp '(' PR <- Sp ')' BL <- Sp '[' @@ -274,34 +287,9 @@ DirtyName <- {} -> DirtyName ]] grammar 'Exp' [[ -Exp <- Sp ExpOr -ExpOr <- (ExpAnd SuffixOr*) -> Binary -ExpAnd <- (ExpCompare SuffixAnd*) -> Binary -ExpCompare <- (ExpBor SuffixComp*) -> Binary -ExpBor <- (ExpBxor SuffixBor*) -> Binary -ExpBxor <- (ExpBand SuffixBxor*) -> Binary -ExpBand <- (ExpBshift SuffixBand*) -> Binary -ExpBshift <- (ExpConcat SuffixBshift*) -> Binary -ExpConcat <- (ExpAdds SuffixConcat*) -> Binary -ExpAdds <- (ExpMuls SuffixAdds*) -> Binary -ExpMuls <- (ExpUnary SuffixMuls*) -> Binary -ExpUnary <- ( SuffixUnary) -> Unary - / ExpPower -ExpPower <- (ExpUnit SuffixPower*) -> Binary - -SuffixOr <- OR (ExpAnd / {} -> DirtyExp) -SuffixAnd <- AND (ExpCompare / {} -> DirtyExp) -SuffixComp <- Comp (ExpBor / {} -> DirtyExp) -SuffixBor <- BOR (ExpBxor / {} -> DirtyExp) -SuffixBxor <- BXOR (ExpBand / {} -> DirtyExp) -SuffixBand <- BAND (ExpBshift / {} -> DirtyExp) -SuffixBshift<- Bshift (ExpConcat / {} -> DirtyExp) -SuffixConcat<- Concat (ExpConcat / {} -> DirtyExp) -SuffixAdds <- Adds (ExpMuls / {} -> DirtyExp) -SuffixMuls <- Muls (ExpUnary / {} -> DirtyExp) -SuffixUnary <- Unary+ (ExpPower / {} -> DirtyExp) -SuffixPower <- POWER (ExpUnary / {} -> DirtyExp) - +Exp <- ((Sp (Op / ExpUnit Sp Op))+ (Sp ExpUnit / {}->DirtyExp)) + -> Exp + / Sp ExpUnit ExpUnit <- Nil / Boolean / String @@ -317,12 +305,17 @@ Prefix <- Sp ({} PL DirtyExp DirtyPR) -> Prefix / FreeName Suffix <- DOT Name / DOT {} -> MissField - / Method (!PL {} -> MissPL)? + / Method (!(Sp CallStart) {} -> MissPL)? / ({} Table {}) -> Call / ({} String {}) -> Call / ({} BL DirtyExp DirtyBR) -> Index / ({} PL CallArgList DirtyPR) -> Call Method <- COLON Name / COLON {} -> MissMethod +CallStart <- PL + / TL + / '"' + / "'" + / '[' '='* '[' DirtyExp <- Exp / {} -> DirtyExp |