diff options
-rw-r--r-- | server/src/parser/ast.lua | 76 | ||||
-rw-r--r-- | server/src/parser/grammar.lua | 12 |
2 files changed, 76 insertions, 12 deletions
diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua index 6d401e44..3e8bc22a 100644 --- a/server/src/parser/ast.lua +++ b/server/src/parser/ast.lua @@ -19,6 +19,7 @@ local function pushError(err) Errs[#Errs+1] = err end +-- goto 单独处理 local RESERVED = { ['and'] = true, ['break'] = true, @@ -29,7 +30,6 @@ local RESERVED = { ['false'] = true, ['for'] = true, ['function'] = true, - ['goto'] = true, ['if'] = true, ['in'] = true, ['local'] = true, @@ -291,7 +291,15 @@ local Defs = { end return string_char(char) end, - Char16 = function (char) + Char16 = function (pos, char) + if State.Version == 'Lua 5.1' then + pushError { + type = 'ERR_ESC', + start = pos-1, + finish = pos, + } + return '' + end return string_char(tonumber(char, 16)) end, CharUtf8 = function (pos, char) @@ -379,7 +387,15 @@ local Defs = { end 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, @@ -786,18 +802,40 @@ local Defs = { action.finish = finish - 1 return action end, - Break = function (finish) + Break = function (finish, ...) if State.Break > 0 then - return { + 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, } - return false + if not ... then + return false + end + local action = select(-1, ...) + if not action then + return false + end + return action end end, BreakStart = function () @@ -830,7 +868,19 @@ local Defs = { end return exp end, - Label = function (name) + 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] @@ -849,7 +899,19 @@ local Defs = { end return name end, - GoTo = function (name) + 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 diff --git a/server/src/parser/grammar.lua b/server/src/parser/grammar.lua index e35b11a2..9185b5b6 100644 --- a/server/src/parser/grammar.lua +++ b/server/src/parser/grammar.lua @@ -6,6 +6,7 @@ local scriptBuf = '' local compiled = {} local parser +-- goto 可以作为名字,合法性之后处理 local RESERVED = { ['and'] = true, ['break'] = true, @@ -16,7 +17,6 @@ local RESERVED = { ['false'] = true, ['for'] = true, ['function'] = true, - ['goto'] = true, ['if'] = true, ['in'] = true, ['local'] = true, @@ -145,7 +145,7 @@ EChar <- 'a' -> ea / "'" / %nl / ('z' (%nl / %s)*) -> '' - / ('x' {X16 X16}) -> Char16 + / ({} 'x' {X16 X16}) -> Char16 / ([0-9] [0-9]? [0-9]?) -> Char10 / ('u{' {} {Word*} '}') -> CharUtf8 -- 错误处理 @@ -397,7 +397,9 @@ Do <- Sp ({} DO DoBody NeedEnd {}) DoBody <- (!END Action)* -> DoBody -Break <- BREAK {} -> Break +Break <- BREAK ({} Semicolon* AfterBreak?) + -> Break +AfterBreak <- Sp !END !UNTIL !ELSEIF !ELSE Action BreakStart <- {} -> BreakStart BreakEnd <- {} -> BreakEnd @@ -407,9 +409,9 @@ ReturnBody <- Sp ({} RETURN MustExpList? {}) -> Return AfterReturn <- Sp !END !UNTIL !ELSEIF !ELSE Action -Label <- LABEL MustName -> Label DirtyLabel +Label <- Sp ({} LABEL MustName DirtyLabel {}) -> Label -GoTo <- GOTO MustName -> GoTo +GoTo <- Sp ({} GOTO MustName {}) -> GoTo If <- Sp ({} IfBody {}) -> If |