Skip to content

Commit c728a9f

Browse files
committed
更新parser
1 parent 45d24b1 commit c728a9f

File tree

4 files changed

+129
-90
lines changed

4 files changed

+129
-90
lines changed

src/parser/compile.lua

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ local function skipComment(isAction)
590590
local result, right = resolveLongString '*/'
591591
pushLongCommentError(left, right)
592592
State.comms[#State.comms+1] = {
593-
type = 'comment.long',
593+
type = 'comment.clong',
594594
start = left,
595595
finish = right,
596596
text = result,
@@ -706,12 +706,13 @@ local function parseLocalAttrs()
706706
else
707707
missSymbol '>'
708708
end
709-
if State.version ~= 'Lua 5.4' then
709+
if State.version ~= 'Lua 5.4'
710+
and State.version ~= 'Lua 5.5' then
710711
pushError {
711712
type = 'UNSUPPORT_SYMBOL',
712713
start = attr.start,
713714
finish = attr.finish,
714-
version = 'Lua 5.4',
715+
version = {'Lua 5.4', 'Lua 5.5'},
715716
info = {
716717
version = State.version
717718
}
@@ -906,13 +907,14 @@ local function parseStringUnicode()
906907
end
907908
if State.version ~= 'Lua 5.3'
908909
and State.version ~= 'Lua 5.4'
910+
and State.version ~= 'Lua 5.5'
909911
and State.version ~= 'LuaJIT'
910912
then
911913
pushError {
912914
type = 'ERR_ESC',
913915
start = leftPos - 2,
914916
finish = rightPos,
915-
version = {'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
917+
version = {'Lua 5.3', 'Lua 5.4', 'Lua 5.5', 'LuaJIT'},
916918
info = {
917919
version = State.version,
918920
}
@@ -932,7 +934,7 @@ local function parseStringUnicode()
932934
end
933935
return nil, offset
934936
end
935-
if State.version == 'Lua 5.4' then
937+
if State.version == 'Lua 5.4' or State.version == 'Lua 5.5' then
936938
if byte < 0 or byte > 0x7FFFFFFF then
937939
pushError {
938940
type = 'UTF8_MAX',
@@ -951,7 +953,7 @@ local function parseStringUnicode()
951953
type = 'UTF8_MAX',
952954
start = leftPos,
953955
finish = rightPos,
954-
version = byte <= 0x7FFFFFFF and 'Lua 5.4' or nil,
956+
version = byte <= 0x7FFFFFFF and {'Lua 5.4', 'Lua 5.5'} or nil,
955957
info = {
956958
min = '000000',
957959
max = '10FFFF',
@@ -1095,7 +1097,7 @@ local function parseShortString()
10951097
type = 'ERR_ESC',
10961098
start = left,
10971099
finish = left + 4,
1098-
version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
1100+
version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'Lua 5.5', 'LuaJIT'},
10991101
info = {
11001102
version = State.version,
11011103
}
@@ -1274,7 +1276,7 @@ local function parseNumber2(start)
12741276
finish = getPosition(offset - 1, 'right'),
12751277
version = 'LuaJIT',
12761278
info = {
1277-
version = 'Lua 5.4',
1279+
version = State.version,
12781280
}
12791281
}
12801282
end
@@ -2673,10 +2675,11 @@ local function parseBinaryOP(asAction, level)
26732675
or token == '<<'
26742676
or token == '>>' then
26752677
if State.version ~= 'Lua 5.3'
2676-
and State.version ~= 'Lua 5.4' then
2678+
and State.version ~= 'Lua 5.4'
2679+
and State.version ~= 'Lua 5.5' then
26772680
pushError {
26782681
type = 'UNSUPPORT_SYMBOL',
2679-
version = {'Lua 5.3', 'Lua 5.4'},
2682+
version = {'Lua 5.3', 'Lua 5.4', 'Lua 5.5'},
26802683
start = op.start,
26812684
finish = op.finish,
26822685
info = {
@@ -3230,6 +3233,7 @@ local function parseLabel()
32303233
local olabel = guide.getLabel(block, name)
32313234
if olabel then
32323235
if State.version == 'Lua 5.4'
3236+
or State.version == 'Lua 5.5'
32333237
or block == guide.getBlock(olabel) then
32343238
pushError {
32353239
type = 'REDEFINED_LABEL',
@@ -3252,7 +3256,7 @@ local function parseLabel()
32523256
type = 'UNSUPPORT_SYMBOL',
32533257
start = left,
32543258
finish = lastRightPosition(),
3255-
version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'LuaJIT'},
3259+
version = {'Lua 5.2', 'Lua 5.3', 'Lua 5.4', 'Lua 5.5', 'LuaJIT'},
32563260
info = {
32573261
version = State.version,
32583262
}
@@ -3544,7 +3548,22 @@ local function parseFor()
35443548
LocalCount = LocalCount + forStateVars
35453549
if name then
35463550
---@cast name parser.object
3547-
local loc = createLocal(name)
3551+
-- In Lua 5.5, for loop variables are treated as constants
3552+
local attrs
3553+
if State.version == 'Lua 5.5' then
3554+
attrs = {
3555+
type = 'localattrs',
3556+
[1] = {
3557+
type = 'localattr',
3558+
start = name.start,
3559+
finish = name.finish,
3560+
parent = nil, -- will be set by createLocal
3561+
[1] = 'const',
3562+
}
3563+
}
3564+
attrs[1].parent = attrs
3565+
end
3566+
local loc = createLocal(name, attrs)
35483567
loc.parent = action
35493568
action.finish = name.finish
35503569
action.bstart = action.finish
@@ -3634,7 +3653,8 @@ local function parseFor()
36343653
missExp()
36353654
end
36363655

3637-
if State.version == 'Lua 5.4' then
3656+
if State.version == 'Lua 5.4'
3657+
or State.version == 'Lua 5.5' then
36383658
forStateVars = 4
36393659
else
36403660
forStateVars = 3
@@ -3648,7 +3668,22 @@ local function parseFor()
36483668
for i = 1, #list do
36493669
local obj = list[i]
36503670
---@cast obj parser.object
3651-
local loc = createLocal(obj)
3671+
-- In Lua 5.5, for loop variables are treated as constants
3672+
local attrs
3673+
if State.version == 'Lua 5.5' then
3674+
attrs = {
3675+
type = 'localattrs',
3676+
[1] = {
3677+
type = 'localattr',
3678+
start = obj.start,
3679+
finish = obj.finish,
3680+
parent = nil, -- will be set by createLocal
3681+
[1] = 'const',
3682+
}
3683+
}
3684+
attrs[1].parent = attrs
3685+
end
3686+
local loc = createLocal(obj, attrs)
36523687
loc.parent = action
36533688
loc.effect = action.finish
36543689
end

src/parser/guide.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,7 @@ local assignTypeMap = {
940940
['setindex'] = true,
941941
['tablefield'] = true,
942942
['tableindex'] = true,
943+
['tableexp'] = true,
943944
['label'] = true,
944945
['doc.class'] = true,
945946
['doc.alias'] = true,

src/parser/luadoc.lua

Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,13 @@ EChar <- 'a' -> ea
5454
/ ([0-9] [0-9]? [0-9]?) -> Char10
5555
/ ('u{' {X16*} '}') -> CharUtf8
5656
Symbol <- ({} {
57-
[:|,;<>()?+#{}]
57+
[:|,;<>()?+#{}*]
5858
/ '[]'
5959
/ '...'
6060
/ '['
6161
/ ']'
6262
/ '-' !'-'
63+
/ '.' !'..'
6364
} {})
6465
-> Symbol
6566
]], {
@@ -71,7 +72,7 @@ Symbol <- ({} {
7172
er = '\r',
7273
et = '\t',
7374
ev = '\v',
74-
name = (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_')) * (m.R('az', 'AZ', '__', '09', '\x80\xff') + m.S('_.*-'))^0,
75+
name = (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_')) * (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_.*-'))^0,
7576
Char10 = function (char)
7677
---@type integer?
7778
char = tonumber(char)
@@ -720,57 +721,62 @@ local function parseString(parent)
720721
return str
721722
end
722723

723-
local function parseCode(parent)
724-
local tp, content = peekToken()
725-
if not tp or tp ~= 'code' then
726-
return nil
727-
end
728-
nextToken()
729-
local code = {
730-
type = 'doc.type.code',
731-
start = getStart(),
732-
finish = getFinish(),
733-
parent = parent,
734-
[1] = content,
735-
}
736-
return code
737-
end
738-
739724
local function parseCodePattern(parent)
740725
local tp, pattern = peekToken()
741-
if not tp or tp ~= 'name' then
726+
if not tp or (tp ~= 'name' and tp ~= 'code') then
742727
return nil
743728
end
744729
local codeOffset
745-
local finishOffset
746730
local content
747-
for i = 2, 8 do
748-
local next, nextContent = peekToken(i)
749-
if not next or TokenFinishs[Ci+i-1] + 1 ~= TokenStarts[Ci+i] then
750-
if codeOffset then
751-
finishOffset = i
752-
break
753-
end
731+
local i = 1
732+
if tp == 'code' then
733+
codeOffset = i
734+
content = pattern
735+
pattern = '%s'
736+
end
737+
while true do
738+
i = i+1
739+
local nextTp, nextContent = peekToken(i)
740+
if not nextTp or TokenFinishs[Ci+i-1] + 1 ~= TokenStarts[Ci+i] then
754741
---不连续的name,无效的
755-
return nil
742+
break
756743
end
757-
if next == 'code' then
758-
if codeOffset and content ~= nextContent then
744+
if nextTp == 'name' then
745+
pattern = pattern .. nextContent
746+
elseif nextTp == 'code' then
747+
if codeOffset then
759748
-- 暂时不支持多generic
760-
return nil
749+
break
761750
end
762751
codeOffset = i
763-
pattern = pattern .. "%s"
752+
pattern = pattern .. '%s'
764753
content = nextContent
765-
elseif next ~= 'name' then
766-
return nil
754+
elseif codeOffset then
755+
-- should be match with Parser "name" mask
756+
if nextTp == 'integer' then
757+
pattern = pattern .. nextContent
758+
elseif nextTp == 'symbol' and (nextContent == '.' or nextContent == '*' or nextContent == '-') then
759+
pattern = pattern .. nextContent
760+
else
761+
break
762+
end
767763
else
768-
pattern = pattern .. nextContent
764+
break
769765
end
770766
end
767+
if not codeOffset then
768+
return nil
769+
end
770+
nextToken()
771771
local start = getStart()
772-
for _ = 2, finishOffset do
773-
nextToken()
772+
local finishOffset = i-1
773+
if finishOffset == 1 then
774+
-- code only, no pattern
775+
pattern = nil
776+
else
777+
for _ = 2, finishOffset do
778+
nextToken()
779+
end
774780
end
775781
local code = {
776782
type = 'doc.type.code',
@@ -834,7 +840,6 @@ function parseTypeUnit(parent)
834840
or parseTable(parent)
835841
or parseTuple(parent)
836842
or parseString(parent)
837-
or parseCode(parent)
838843
or parseInteger(parent)
839844
or parseBoolean(parent)
840845
or parseParen(parent)
@@ -926,7 +931,7 @@ function parseType(parent)
926931
local function pushResume()
927932
local comments
928933
for i = 0, 100 do
929-
local nextComm = NextComment(i,'peek')
934+
local nextComm = NextComment(i, true)
930935
if not nextComm then
931936
return false
932937
end
@@ -1707,10 +1712,9 @@ local function trimTailComment(text)
17071712
end
17081713

17091714
local function buildLuaDoc(comment)
1710-
local text = comment.text
1711-
local startPos = (comment.type == 'comment.short' and text:match '^%-%s*@()')
1712-
or (comment.type == 'comment.long' and text:match '^@()')
1713-
if not startPos then
1715+
local headPos = (comment.type == 'comment.short' and comment.text:match '^%-%s*@()')
1716+
or (comment.type == 'comment.long' and comment.text:match '^%s*@()')
1717+
if not headPos then
17141718
return {
17151719
type = 'doc.comment',
17161720
start = comment.start,
@@ -1719,42 +1723,47 @@ local function buildLuaDoc(comment)
17191723
comment = comment,
17201724
}
17211725
end
1722-
local startOffset = comment.start
1726+
-- absolute position of `@` symbol
1727+
local startOffset = comment.start + headPos
17231728
if comment.type == 'comment.long' then
1724-
startOffset = startOffset + #comment.mark - 2
1729+
startOffset = comment.start + headPos + #comment.mark - 2
17251730
end
17261731

1727-
local doc = text:sub(startPos)
1732+
local doc = comment.text:sub(headPos)
17281733

1729-
parseTokens(doc, startOffset + startPos)
1734+
parseTokens(doc, startOffset)
17301735
local result, rests = convertTokens(doc)
17311736
if result then
17321737
result.range = math.max(comment.finish, result.finish)
17331738
local finish = result.firstFinish or result.finish
17341739
if rests then
17351740
for _, rest in ipairs(rests) do
1736-
rest.range = comment.finish
1737-
finish = rest.firstFinish or result.finish
1741+
rest.range = math.max(comment.finish, rest.finish)
1742+
finish = rest.firstFinish or rest.finish
17381743
end
17391744
end
1740-
local cstart = text:find('%S', finish - comment.start)
1741-
if cstart and cstart < comment.finish then
1745+
1746+
-- `result` can be a multiline annotation or an alias, while `doc` is the first line, so we can't parse comment
1747+
if finish >= comment.finish then
1748+
return result, rests
1749+
end
1750+
1751+
local cstart = doc:find('%S', finish - startOffset)
1752+
if cstart then
17421753
result.comment = {
17431754
type = 'doc.tailcomment',
1744-
start = cstart + comment.start,
1755+
start = startOffset + cstart,
17451756
finish = comment.finish,
17461757
parent = result,
1747-
text = trimTailComment(text:sub(cstart)),
1758+
text = trimTailComment(doc:sub(cstart)),
17481759
}
17491760
if rests then
17501761
for _, rest in ipairs(rests) do
17511762
rest.comment = result.comment
17521763
end
17531764
end
17541765
end
1755-
end
17561766

1757-
if result then
17581767
return result, rests
17591768
end
17601769

@@ -2172,7 +2181,7 @@ local function bindDocs(state)
21722181
if doc.specialBindGroup then
21732182
bindDocWithSources(sources, doc.specialBindGroup)
21742183
binded = nil
2175-
elseif isTailComment(text, doc) and doc.type ~= "doc.class" and doc.type ~= "doc.field" then
2184+
elseif isTailComment(text, doc) and doc.type ~= "doc.field" then
21762185
bindDocWithSources(sources, binded)
21772186
binded = nil
21782187
else

0 commit comments

Comments
 (0)