Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://anggtwu.net/LUA/ELLua1.lua.html -- http://anggtwu.net/LUA/ELLua1.lua -- (find-angg "LUA/ELLua1.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- ELLua1.lua: a reimplementation on ELpeg1 of the Lua grammar in -- lpregrex. Status: INCOMPLETE. -- -- (defun e () (interactive) (find-angg "LUA/ELLua1.lua")) -- (defun b () (interactive) (find-angg "LUA/ELpeg1.lua")) -- (defun o () (interactive) (find-angg "LUA/Gram3.lua")) -- (find-lpegrexfile "parsers/lua.lua") -- (find-angg "LUA/ELpeg1.lua" "Keywords") -- «.Block» (to "Block") -- «.Block-tests» (to "Block-tests") -- «.Number» (to "Number") -- «.Number-tests» (to "Number-tests") -- «.Call» (to "Call") -- «.Call-tests» (to "Call-tests") -- «.opor» (to "opor") -- «.opor-tests» (to "opor-tests") -- «.string-etc» (to "string-etc") require "ELpeg1" -- (find-angg "LUA/ELpeg1.lua") gr,V,VA,VE,PE = Gram.new() wordpat = Cs(R("__", "AZ", "az") * R("__", "AZ", "az", "09")^0) keywords,K,KE,KW,NKW = Keywords.from(wordpat) V.S = (S" \t\n")^0 _ = V.S --s = V.S V[","] = P"," V["]"] = P"]" V["}"] = P"}" V[")"] = P")" -- chunk <-- SHEBANG? SKIP Block (!.)^UnexpectedSyntax -- ____ _ _ -- | __ )| | ___ ___| | __ -- | _ \| |/ _ \ / __| |/ / -- | |_) | | (_) | (__| < -- |____/|_|\___/ \___|_|\_\ -- -- «Block» (to ".Block") -- (find-lpegrexfile "parsers/lua.lua" "\nBlock") -- -- Block <== ( Label / Return / Break / Goto / Do -- / While / Repeat / If / ForNum / ForIn -- / FuncDef / FuncDecl / VarDecl / Assign / call / `;`)* -- Label <== `::` @NAME @`::` -- Return <== `return` exprlist? -- Break <== `break` -- Goto <== `goto` @NAME -- Do <== `do` Block @`end` -- While <== `while` @expr @`do` Block @`end` -- Repeat <== `repeat` Block @`until` @expr -- If <== `if` @expr @`then` Block -- (`elseif` @expr @`then` Block)* -- (`else` Block)? -- @`end` -- ForNum <== `for` Id -- `=` @expr @`,` @expr (`,` @expr)? -- @`do` Block @`end` -- ForIn <== `for` @idlist `in` @exprlist -- @`do` Block @`end` -- FuncDef <== `function` @funcname funcbody -- FuncDecl <== `local` `function` @Id funcbody -- VarDecl <== `local` @iddecllist (`=` @exprlist)? -- Assign <== varlist `=` @exprlist -- V.Block = ((V.Label + V.Return + V.Break + V.Goto + V.Do + V.While + V.Repeat + V.If + V.ForNum + V.ForIn + V.FuncDef + V.FuncDecl + V.VarDecl + V.Assign + V.call + P";")*_)^0 VA.Label = P"::" * VE.NAME * PE"::" VA.Return = K"return" *_* V.exprlist^-1 VA.Break = K"break" VA.Goto = K"goto" *_* VE.NAME VA.Do = K"do" *_* V.Block *_* KE"end" VA.While = K"while" *_* VE.expr *_* KE"do" *_* V.Block *_* KE"end" VA.Repeat = K"repeat" *_* V.Block *_* KE"until" *_* V.expr VA.If = K"if" *_* VE.expr *_* KE"then" *_* V.Block * (K"elseif" *_* V.expr *_* KE"then" *_* V.Block)^0 * (K"else" *_* V.Block)^-1 * KE"end" VA.ForNum = K"for" *_* V.Id *_ * P"=" *_* VE.expr *_* VE[","] *_* VE.expr *_* (P"," *_* VE.expr *_)^-1 * KE"do" *_* V.Block *_* KE"end" VA.ForIn = K"for" *_* V.idlist *_* K"in" *_* V.exprlist *_ * KE"do" *_* V.Block *_* KE"end" VA.FuncDef = K"function" *_* VE.funcname *_* VE.funcbody VA.FuncDecl = K"local" *_* K"function" *_* VE.Id *_* VE.funcbody VA.VarDecl = K"local" *_* V.iddecllist * (_* P"=" *_* V.exprlist)^-1 VA.Assign = V.varlist *_* P"=" *_* V.exprlist -- «Block-tests» (to ".Block-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ELLua1.lua" = keywords = gr:cm("Block", "") = gr:cm("Block", "a b") = gr:cm("Block", "a=b") = gr:cm("Block", "return") = gr:cm("Block", "return a,b,c") = gr:cm("Block", "break") = gr:cm("Block", "goto foo") = gr:cm("Block", "do a=b end") = gr:cm("Block", "do a=b c(d) end") = gr:cm("Block", "do a=b c(d) e end") = gr:cm("Block", "while a do end") = gr:cm("Block", "while a do b=c end") = gr:cm("Block", "repeat a=b until c") = gr:cm("Block", "repeat a until c") = gr:cm("Block", "if a then b=c end") = gr:cm("Block", "if a then b=c else d=e end") = gr:cm("Block", "if a then b=c else d=e else f=g end") = gr:cm("Block", "if a then b end") = gr:cm("Block", "if a then b=c elseif d then e=f end") = gr:cm("Block", "for a=b do end") = gr:cm("Block", "for a=b,c do end") = gr:cm("Block", "for a=b,c,d do end") = gr:cm("Block", "for a=b,c,d,e do end") = gr:cm("Block", "for a,b in c,d do end") = gr:cm("Block", "function a (c) end") = gr:cm("Block", "function a.b(c) end") = gr:cm("Block", "function a end") = gr:cm("Block", "function (c) end") = gr:cm("Block", "local function a (c) end") = gr:cm("Block", "local function a.b(c) end") --]] -- _ _ _ -- | \ | |_ _ _ __ ___ | |__ ___ _ __ -- | \| | | | | '_ ` _ \| '_ \ / _ \ '__| -- | |\ | |_| | | | | | | |_) | __/ | -- |_| \_|\__,_|_| |_| |_|_.__/ \___|_| -- -- «Number» (to ".Number") -- (find-lpegrexfile "parsers/lua.lua" "\nNumber") -- -- Number <== NUMBER->tonumber SKIP -- String <== STRING SKIP -- Boolean <== `false`->tofalse / `true`->totrue -- Nil <== `nil` -- Varargs <== `...` -- Id <== NAME -- IdDecl <== NAME (`<` @NAME @`>`)? -- Function <== `function` funcbody -- Table <== `{` (field (fieldsep field)* fieldsep?)? @`}` -- Paren <== `(` @expr @`)` -- Pair <== `[` @expr @`]` @`=` @expr -- / NAME `=` @expr V.Number = Cast("N", Cs(R("09")^1)) -- integers only V.String = Cast("Str", Cs(V.STRING)) V.Boolean = Cs(P"false" + P"true") V.Nil = Cs(P"nil") V.Varargs = Cs(P"...") VA.Id = Cs(NKW) VA.IdDecl = Cs(NKW) V.fieldsep = S",;" V.Function = P"notyet" V.Table = Cast("{}", P"{" *_* zeroormorecc(V.field, V.fieldsep) *_* P"}") V.Paren = P"(" *_* V.expr *_* P")" V.Pair = Cast("Pair", V.PairL *_*P"="*_* V.expr) V.PairL = P"["*_* V.expr *_*P"]" + V.NAME -- «Number-tests» (to ".Number-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ELLua1.lua" --]] -- ____ _ _ -- / ___|__ _| | | -- | | / _` | | | -- | |__| (_| | | | -- \____\__,_|_|_| -- -- «Call» (to ".Call") -- (find-lpegrexfile "parsers/lua.lua" "\nCall") -- (find-lpegrexfile "parsers/lua.lua" "\nindexsuffix") -- (find-lpegrexfile "parsers/lua.lua" "\nvar ") -- (find-lpegrexfile "parsers/lua.lua" "\nfuncbody") -- (find-lpegrexfile "parsers/lua.lua" "\ncallargs") -- -- Call <== callargs -- CallMethod <== `:` @NAME @callargs -- DotIndex <== `.` @NAME -- ColonIndex <== `:` @NAME -- KeyIndex <== `[` @expr @`]` -- -- indexsuffix <-- DotIndex / KeyIndex -- callsuffix <-- Call / CallMethod -- -- var <-- (exprprimary (callsuffix+ indexsuffix / indexsuffix)+)~>rfoldright / Id -- call <-- (exprprimary (indexsuffix+ callsuffix / callsuffix)+)~>rfoldright -- exprsuffixed <-- (exprprimary (indexsuffix / callsuffix)*)~>rfoldright -- funcname <-- (Id DotIndex* ColonIndex?)~>rfoldright -- -- funcbody <-- @`(` funcargs @`)` Block @`end` -- field <-- Pair / expr -- fieldsep <-- `,` / `;` -- -- callargs <-| `(` (expr (`,` @expr)*)? @`)` / Table / String -- idlist <-| Id (`,` @Id)* -- iddecllist <-| IdDecl (`,` @IdDecl)* -- funcargs <-| (Id (`,` Id)* (`,` Varargs)? / Varargs)? -- exprlist <-| expr (`,` @expr)* -- varlist <-| var (`,` @var)* V.Call = V.callargs V.CallMethod = P":"*_* V.NAME *_* V.callargs V.DotIndex = P"."*_* V.NAME V.ColonIndex = P":"*_* V.NAME V.KeyIndex = P"["*_* V.expr *_*P"]" V.indexsuffix = V.DotIndex + V.KeyIndex V.callsuffix = V.Call + V.CallMethod V.var = assocpost (V.exprprimary, endingwith(V.callsuffix, V.indexsuffix)) + V.Id V.call = assocpostp(V.exprprimary, endingwith(V.indexsuffix, V.callsuffix)) V.exprsuffixed = assocpost (V.exprprimary, V.indexsuffix + V.callsuffix) V.funcname = Ct(V.Id * (_*V.DotIndex)^0 * (_*V.ColonIndex)^-1) / foldpost V.funcbody = P"(" *_* V.funcargs *_* P")" *_* V.Block *_* KE"end" V.field = V.Pair + V.expr V.fieldsep = P"," + P";" V.callargs = Cast("()", P"("*_* zeroormorec(V.expr, P",") *_*P")") + V.Table + V.String V.idlist = oneormorec (V.Id, P",") V.iddecllist = oneormorec (V.IdDecl, P",") V.funcargs = oneormorec (V.Id, P",") * (_*P","*_* V.Varargs)^-1 + V.Varargs^-1 V.exprlist = oneormorec (V.expr, P",") V.varlist = oneormorec (V.var, P",") -- «Call-tests» (to ".Call-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ELLua1.lua" = gr:cm("var", "a") = gr:cm("call", "a") = gr:cm("var", "a.b") = gr:cm("var", "a.b(c)") = gr:cm("call", "a.b(c)") = gr:cm("var", "a.b(c).d") = gr:cm("var", "a:b(c).d") = gr:cm("var", "a[234].d") = gr:cm("var", "a[234]") = gr:cm("funcname", "a.b.c:d") = gr:cm("callargs", "(a, bc, def)") = gr:cm("callargs", "(a, bc, def, ...)") = gr:cm("callargs", "(...)") = gr:cm("callargs", "()") = gr:cm("callargs", "'abc'") = gr:cm("callargs", "{abc}") --]] -- -- ___ _ __ ___ _ __ -- / _ \| '_ \ / _ \| '__| -- | (_) | |_) | (_) | | -- \___/| .__/ \___/|_| -- |_| -- -- «opor» (to ".opor") -- (find-lpegrexfile "parsers/lua.lua" "\nopor ") -- (find-lpegrexfile "parsers/lua.lua" "\nexpr ") -- opor :BinaryOp <== `or`->'or' @exprand -- opand :BinaryOp <== `and`->'and' @exprcmp -- opcmp :BinaryOp <== (`==`->'eq' / `~=`->'ne' / `<=`->'le' / -- `>=`->'ge' / `<`->'lt' / `>`->'gt') @exprbor -- opbor :BinaryOp <== `|`->'bor' @exprbxor -- opbxor :BinaryOp <== `~`->'bxor' @exprband -- opband :BinaryOp <== `&`->'band' @exprbshift -- opbshift :BinaryOp <== (`<<`->'shl' / `>>`->'shr') @exprconcat -- opconcat :BinaryOp <== `..`->'concat' @exprconcat -- oparit :BinaryOp <== (`+`->'add' / `-`->'sub') @exprfact -- opfact :BinaryOp <== (`*`->'mul' / `//`->'idiv' / `/`->'div' / `%`->'mod') @exprunary -- oppow :BinaryOp <== `^`->'pow' @exprunary -- opunary :UnaryOp <== (`not`->'not' / `#`->'len' / `-`->'unm' / `~`->'bnot') @exprunary -- -- expr <-- expror -- expror <-- (exprand opor*)~>foldleft -- exprand <-- (exprcmp opand*)~>foldleft -- exprcmp <-- (exprbor opcmp*)~>foldleft -- exprbor <-- (exprbxor opbor*)~>foldleft -- exprbxor <-- (exprband opbxor*)~>foldleft -- exprband <-- (exprbshift opband*)~>foldleft -- exprbshift <-- (exprconcat opbshift*)~>foldleft -- exprconcat <-- (exprarit opconcat*)~>foldleft -- exprarit <-- (exprfact oparit*)~>foldleft -- exprfact <-- (exprunary opfact*)~>foldleft -- exprunary <-- opunary / exprpow -- exprpow <-- (exprsimple oppow*)~>foldleft -- exprsimple <-- Nil / Boolean / Number / String / Varargs / Function / Table / exprsuffixed -- exprprimary <-- Id / Paren V.opor = anyof "or" V.opand = anyof "and" V.opcmp = anyof "== ~= <= >= < >" V.opbor = anyof "|" V.opbxor = anyof "~" V.opband = anyof "&" V.opbshift = anyof "<< >>" V.opconcat = anyof ".." V.oparit = anyof "+ -" V.opfact = anyof "* // / %" V.oppow = anyof "^" V.opunary = anyof "not # - ~" V.expr = V.expror V.expror = assocl(V.exprand, V.opor ) V.exprand = assocl(V.exprcmp, V.opand ) V.exprcmp = assocl(V.exprbor, V.opcmp ) V.exprbor = assocl(V.exprbxor, V.opbor ) V.exprbxor = assocl(V.exprband, V.opbxor ) V.exprband = assocl(V.exprbshift, V.opband ) V.exprbshift = assocl(V.exprconcat, V.opbshift) V.exprconcat = assocl(V.exprarit, V.opconcat) V.exprarit = assocl(V.exprfact, V.oparit ) V.exprfact = assocl(V.exprunary, V.opfact ) V.exprunary = assocpre(V.opunary, V.exprpow ) V.exprpow = assocr(V.exprsimple, V.oppow ) V.exprsimple = V.Nil + V.Boolean + V.Number + V.String + V.Varargs + V.Function + V.Table + V.exprsuffixed V.exprprimary = V.Id + V.Paren -- «opor-tests» (to ".opor-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ELLua1.lua" = gr:cm("expr", "2 + 3 * 'a'") = gr:cm("expr", "2^3^4 - 5*6*7 - (8 / 9)") = gr:cm("expr", "{a=3, ['b']=4, 5}") = gr:cm("expr", "a") = gr:cm("expr", "a.b") --]] -- _ _ _ -- ___| |_ _ __(_)_ __ __ _ ___| |_ ___ -- / __| __| '__| | '_ \ / _` | / _ \ __/ __| -- \__ \ |_| | | | | | | (_| |_ | __/ || (__ -- |___/\__|_| |_|_| |_|\__, ( ) \___|\__\___| -- |___/|/ -- -- «string-etc» (to ".string-etc") -- (find-lpegrexfile "parsers/lua.lua" "STRING_SHRT") -- STRING <-- STRING_SHRT / STRING_LONG -- STRING_LONG <-- {:LONG_OPEN {LONG_CONTENT} @LONG_CLOSE:} -- STRING_SHRT <-- {:QUOTE_OPEN {~QUOTE_CONTENT~} @QUOTE_CLOSE:} -- QUOTE_OPEN <-- {:qe: ['"] :} -- QUOTE_CONTENT <-- (ESCAPE_SEQ / !(QUOTE_CLOSE / LINEBREAK) .)* -- QUOTE_CLOSE <-- =qe -- ESCAPE_SEQ <-- '\'->'' @ESCAPE -- ESCAPE <-- [\'"] / -- ('n' $10 / 't' $9 / 'r' $13 / 'a' $7 / 'b' $8 / 'v' $11 / 'f' $12)->tochar / -- ('x' {HEX_DIGIT^2} $16)->tochar / -- ('u' '{' {HEX_DIGIT^+1} '}' $16)->toutf8char / -- ('z' SPACE*)->'' / -- (DEC_DIGIT DEC_DIGIT^-1 !DEC_DIGIT / [012] DEC_DIGIT^2)->tochar / -- (LINEBREAK $10)->tochar -- NUMBER <-- {HEX_NUMBER / DEC_NUMBER} -- HEX_NUMBER <-- '0' [xX] @HEX_PREFIX ([pP] @EXP_DIGITS)? -- DEC_NUMBER <-- DEC_PREFIX ([eE] @EXP_DIGITS)? -- HEX_PREFIX <-- HEX_DIGIT+ ('.' HEX_DIGIT*)? / '.' HEX_DIGIT+ -- DEC_PREFIX <-- DEC_DIGIT+ ('.' DEC_DIGIT*)? / '.' DEC_DIGIT+ -- EXP_DIGITS <-- [+-]? DEC_DIGIT+ -- COMMENT <-- '--' (COMMENT_LONG / COMMENT_SHRT) -- COMMENT_LONG <-- (LONG_OPEN LONG_CONTENT @LONG_CLOSE)->0 -- COMMENT_SHRT <-- (!LINEBREAK .)* -- LONG_CONTENT <-- (!LONG_CLOSE .)* -- LONG_OPEN <-- '[' {:eq: '='*:} '[' LINEBREAK? -- LONG_CLOSE <-- ']' =eq ']' -- NAME <-- !KEYWORD {NAME_PREFIX NAME_SUFFIX?} SKIP -- NAME_PREFIX <-- [_a-zA-Z] -- NAME_SUFFIX <-- [_a-zA-Z0-9]+ -- SHEBANG <-- '#!' (!LINEBREAK .)* LINEBREAK? -- SKIP <-- (SPACE+ / COMMENT)* -- LINEBREAK <-- %cn %cr / %cr %cn / %cn / %cr -- SPACE <-- %sp -- HEX_DIGIT <-- [0-9a-fA-F] -- DEC_DIGIT <-- [0-9] -- EXTRA_TOKENS <-- `[[` `[=` `--` -- unused rule, here just to force defining these tokens -- (find-lpegrexfile "parsers/lua.lua" "\nSTRING_SHRT") V.STRING = V.STRING_SHRT V.STRING_SHRT = Cs(V.QUOTE_OPEN * V.QUOTE_CONTENT * V.QUOTE_CLOSE) V.QUOTE_OPEN = P"'" V.QUOTE_CONTENT = (1-P"'")^0 V.QUOTE_CLOSE = P"'" -- (find-lpegrexfile "parsers/lua.lua" "NAME_PREFIX") V.NAME = Cs(V.NAME_PREFIX * V.NAME_SUFFIX^0) V.NAME_PREFIX = R("__","AZ","az") V.NAME_SUFFIX = R("__","AZ","az","09") -- VA.NAME = Cs(NKW) -- Should I use this instead? -- Local Variables: -- coding: utf-8-unix -- End: