summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/parser/ast.lua199
-rw-r--r--server/src/parser/grammar.lua51
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