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