diff --git a/src/parser/ast.lua b/src/parser/ast.lua index ac97d51..b730a65 100644 --- a/src/parser/ast.lua +++ b/src/parser/ast.lua @@ -1124,6 +1124,9 @@ local Defs = { end, -- EmmyLua 支持 + Emmy = function (emmy) + State.emmy[#State.emmy+1] = emmy + end, EmmyName = function (start, str) return { type = 'emmyName', @@ -1586,6 +1589,7 @@ return function (self, lua, mode, version) Label = {{}}, Dots = {true}, Version = version, + emmy = {}, } local suc, res, err = xpcall(self.grammar, debug.traceback, self, lua, mode, Defs) if not suc then @@ -1593,7 +1597,7 @@ return function (self, lua, mode, version) end if not res then pushError(err) - return nil, Errs + return nil, Errs, State end - return res, Errs + return res, Errs, State end diff --git a/src/parser/grammar.lua b/src/parser/grammar.lua index 54b03e2..dd44063 100644 --- a/src/parser/grammar.lua +++ b/src/parser/grammar.lua @@ -91,13 +91,15 @@ local function errorpos(pos, err) end grammar 'Comment' [[ -Comment <- '--' (LongComment / ShortComment) +Comment <- '--' (Emmy / LongComment / ShortComment) LongComment <- ('[' {} {:eq: '='* :} {} '[' (!CommentClose .)* (CommentClose / {})) -> LongComment CommentClose <- ']' =eq ']' ShortComment <- (!%nl .)* +-- 占位 +Emmy <- !. ]] grammar 'Sp' [[ @@ -343,7 +345,7 @@ ArgList <- (DOTS -> DotsAsArg / Name / Sp {} COMMA)* Table <- Sp ({} TL TableFields? DirtyTR) -> Table -TableFields <- (Emmy / TableSep {} / TableField)+ +TableFields <- (TableSep {} / TableField)+ TableSep <- COMMA / SEMICOLON TableField <- NewIndex / NewField / Exp NewIndex <- Sp (Index NeedAssign DirtyExp) @@ -356,7 +358,7 @@ Function <- Sp ({} FunctionBody {}) FuncArg <- PL {} ArgList {} NeedPR / {} {} -> MissPL Nothing {} FunctionBody<- FUNCTION BlockStart FuncArg - (Emmy / !END Action)* + (!END Action)* BlockEnd NeedEnd @@ -366,7 +368,6 @@ BlockEnd <- {} -> BlockEnd -- 纯占位,修改了 `relabel.lua` 使重复定义不抛错 Action <- !END . Set <- END -Emmy <- '---@' ]] grammar 'Action' [[ @@ -401,7 +402,7 @@ SimpleList <- (Simple (COMMA Simple)*) Do <- Sp ({} DO DoBody NeedEnd {}) -> Do -DoBody <- (Emmy / !END Action)* +DoBody <- (!END Action)* -> DoBody Break <- BREAK ({} Semicolon* AfterBreak?) @@ -432,15 +433,15 @@ IfBody <- IfHead (ElsePart -> ElseBlock)? NeedEnd IfPart <- IF DirtyExp THEN - {} (Emmy / !ELSEIF !ELSE !END Action)* {} + {} (!ELSEIF !ELSE !END Action)* {} / IF DirtyExp {}->MissThen {} {} ElseIfPart <- ELSEIF DirtyExp THEN - {} (Emmy / !ELSE !ELSEIF !END Action)* {} + {} (!ELSE !ELSEIF !END Action)* {} / ELSEIF DirtyExp {}->MissThen {} {} ElsePart <- ELSE - {} (Emmy / !END Action)* {} + {} (!END Action)* {} For <- Loop / In / FOR @@ -449,7 +450,7 @@ Loop <- Sp ({} LoopBody {}) -> Loop LoopBody <- FOR LoopStart LoopFinish LoopStep NeedDo BreakStart - (Emmy / !END Action)* + (!END Action)* BreakEnd NeedEnd LoopStart <- MustName ASSIGN DirtyExp @@ -462,7 +463,7 @@ In <- Sp ({} InBody {}) -> In InBody <- FOR InNameList NeedIn ExpList NeedDo BreakStart - (Emmy / !END Action)* + (!END Action)* BreakEnd NeedEnd InNameList <- &IN DirtyName @@ -472,7 +473,7 @@ While <- Sp ({} WhileBody {}) -> While WhileBody <- WHILE DirtyExp NeedDo BreakStart - (Emmy / !END Action)* + (!END Action)* BreakEnd NeedEnd @@ -480,7 +481,7 @@ Repeat <- Sp ({} RepeatBody {}) -> Repeat RepeatBody <- REPEAT BreakStart - (Emmy / !UNTIL Action)* + (!UNTIL Action)* BreakEnd NeedUntil DirtyExp @@ -502,20 +503,17 @@ NamedFunction -> NamedFunction FunctionNamedBody <- FUNCTION FuncName BlockStart FuncArg - (Emmy / !END Action)* + (!END Action)* BlockEnd NeedEnd FuncName <- (MustName (DOT MustName)* FuncMethod?) -> Simple FuncMethod <- COLON Name / COLON {} -> MissMethod - --- 占位 -Emmy <- '---@' ]] grammar 'Emmy' [[ -Emmy <- EmmySp '---@' EmmyBody ShortComment -EmmySp <- (!'---@' Comment / %s / %nl)* +Emmy <- ('-@' EmmyBody ShortComment) + -> Emmy EmmyBody <- 'class' %s+ EmmyClass -> EmmyClass / 'type' %s+ EmmyType -> EmmyType / 'alias' %s+ EmmyAlias -> EmmyAlias @@ -591,7 +589,7 @@ EmmySee <- {} MustEmmyName %s* '#' %s* MustEmmyName {} grammar 'Lua' [[ Lua <- Head? - (Emmy / Action)* -> Lua + Action* -> Lua BlockEnd Sp Head <- '#' (!%nl .)* diff --git a/test/ast/Emmy.lua b/test/ast/Emmy.lua index 1e19ddf..c451e72 100644 --- a/test/ast/Emmy.lua +++ b/test/ast/Emmy.lua @@ -1,4 +1,4 @@ -CHECK [[ +CHECK_EMMY [[ ---@class Class local x = 1 ]] @@ -14,24 +14,9 @@ local x = 1 [1] = 'Class', }, }, - [2] = { - type = 'local', - [1] = { - type = 'name', - start = 23, - finish = 23, - [1] = 'x', - }, - [2] = { - type = 'number', - start = 27, - finish = 27, - [1] = 1, - } - } } -CHECK [[ +CHECK_EMMY [[ ---@class Class : SuperClass local x = 1 ]] @@ -53,24 +38,9 @@ local x = 1 [1] = 'SuperClass', }, }, - [2] = { - type = 'local', - [1] = { - type = 'name', - start = 36, - finish = 36, - [1] = 'x', - }, - [2] = { - type = 'number', - start = 40, - finish = 40, - [1] = 1, - } - } } -CHECK [[ +CHECK_EMMY [[ ---@class Class x = 1 ]] @@ -86,24 +56,9 @@ x = 1 [1] = 'Class', }, }, - [2] = { - type = 'set', - [1] = { - type = 'name', - start = 17, - finish = 17, - [1] = 'x', - }, - [2] = { - type = 'number', - start = 21, - finish = 21, - [1] = 1, - } - } } -CHECK [[ +CHECK_EMMY [[ ---@type Type x = 1 ]] @@ -119,24 +74,9 @@ x = 1 [1] = 'Type', }, }, - [2] = { - type = 'set', - [1] = { - type = 'name', - start = 15, - finish = 15, - [1] = 'x', - }, - [2] = { - type = 'number', - start = 19, - finish = 19, - [1] = 1, - } - } } -CHECK [[ +CHECK_EMMY [[ ---@type Type1|Type2|Type3 x = 1 ]] @@ -164,24 +104,9 @@ x = 1 [1] = 'Type3', }, }, - [2] = { - type = 'set', - [1] = { - type = 'name', - start = 28, - finish = 28, - [1] = 'x', - }, - [2] = { - type = 'number', - start = 32, - finish = 32, - [1] = 1, - } - } } -CHECK [[ +CHECK_EMMY [[ ---@alias Handler LongType x = 1 ]] @@ -208,24 +133,9 @@ x = 1 }, }, }, - [2] = { - type = 'set', - [1] = { - type = 'name', - start = 28, - finish = 28, - [1] = 'x', - }, - [2] = { - type = 'number', - start = 32, - finish = 32, - [1] = 1, - } - } } -CHECK [[ +CHECK_EMMY [[ ---@param a1 t1 ---@param a2 t2 ---@param a3 t3 @@ -293,7 +203,7 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ ---@return Type1|Type2|Type3 ]] { @@ -325,7 +235,7 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ ---@field open function ]] { @@ -354,7 +264,7 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ ---@field private open function|string ]] { @@ -389,7 +299,7 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ ---@generic T ]] { @@ -406,7 +316,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@generic T : handle ]] { @@ -434,7 +344,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@generic T : handle, K : handle ]] { @@ -481,7 +391,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@vararg string ]] { @@ -501,7 +411,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@language JSON ]] { @@ -516,7 +426,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@type Type[] ]] { @@ -528,7 +438,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@type table ]] { @@ -561,7 +471,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@type fun(key1:t1|t2[], key2:t3):table ]] { @@ -639,7 +549,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@param event string | "'onClosed'" | "'onData'" ]] { @@ -679,7 +589,7 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ ---@see loli#pants ]] { @@ -702,7 +612,7 @@ CHECK [[ } } -CHECK [[ +CHECK_EMMY [[ ---@class Class ]] @@ -720,7 +630,7 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ ---@ ---@cl ]] @@ -739,85 +649,41 @@ CHECK [[ }, } -CHECK [[ +CHECK_EMMY [[ local t = { ---@type string x = 1, } ]] { - [1] = { - type = "local", - [1] = { - type = "name", - start = 7, - finish = 7, - [1] = "t", - }, - [2] = { - type = "table", - start = 11, - finish = 44, - [1] = { - type = "emmyType", - start = 26, - finish = 31, - [1] = { - type = "emmyName", - start = 26, - finish = 31, - [1] = "string", - }, - }, - [2] = { - type = "pair", - start = 37, - finish = 41, - [1] = { - type = "name", - start = 37, - finish = 37, - [1] = "x", - }, - [2] = { - type = "number", - start = 41, - finish = 41, - [1] = 1, - }, - }, + [1] = { + type = "emmyType", + start = 26, + finish = 31, + [1] = { + type = "emmyName", + start = 26, + finish = 31, + [1] = "string", }, }, } -CHECK [[ +CHECK_EMMY [[ local function f() ---@ end ]] { - [1] = { - type = "localfunction", - start = 1, - finish = 31, - argStart = 17, - argFinish = 18, - name = { - [1] = "f", - finish = 16, - start = 16, - type = "name", - }, - [1] = { - type = "emmyIncomplete", - start = 27, - finish = 27, - [1] = "", - }, + [1] = { + type = "emmyIncomplete", + start = 27, + finish = 27, + [1] = "", }, } -CHECK '---@type fun' +CHECK_EMMY '---@type fun' { [1] = { type = "emmyFunctionType", diff --git a/test/ast/init.lua b/test/ast/init.lua index fafd24e..54ae158 100644 --- a/test/ast/init.lua +++ b/test/ast/init.lua @@ -2,6 +2,7 @@ local parser = require 'parser' local fs = require 'bee.filesystem' rawset(_G, 'CHECK', false) +rawset(_G, 'CHECK_EMMY', false) local function eq(a, b) local tp1, tp2 = type(a), type(b) @@ -44,6 +45,20 @@ local function test(type) end end end + CHECK_EMMY = function (buf) + return function (target_emmy) + local my_ast, err, state = parser:ast(buf, type, 'Lua 5.4') + if not my_ast then + error(('语法树生成失败:%s'):format(err)) + end + if not eq(state.emmy, target_emmy) then + fs.create_directory(ROOT / 'test' / 'log') + io.save(ROOT / 'test' / 'log' / 'my_emmy.ast', table.dump(state.emmy)) + io.save(ROOT / 'test' / 'log' / 'target_emmy.ast', table.dump(target_emmy)) + error(('语法树不相等:%s\n%s'):format(type, buf)) + end + end + end require('ast.' .. type) end