|
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: