diff options
Diffstat (limited to 'src/parser_min.lua')
| -rw-r--r-- | src/parser_min.lua | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/src/parser_min.lua b/src/parser_min.lua new file mode 100644 index 0000000..a627cc4 --- /dev/null +++ b/src/parser_min.lua @@ -0,0 +1,554 @@ +local a, b, d, e, c = "String", "errorinfo", "function", "cannot use '...' outside a vararg function", "SuffixedExp" + local f = {} + local g = require("lpeg") + local h + + if include ~= nil then + h = include("./scope.lua") + else + h = dofile("../src/scope.lua") + end + + g.locale(g) + local i, j, k = g.P, g.S, g.V + local l, m, n, o = g.C, g.Carg, g.Cb, g.Cc + local p, q, r, s, t = g.Cf, g.Cg, g.Cmt, g.Cp, g.Ct + local u, v, w = g.alpha, g.digit, g.alnum + local x = g.xdigit + local y = g.space + local z = h.lineno + local A, B = h.new_scope, h.end_scope + local C, D = h.new_function, h.end_function + local E, F = h.begin_loop, h.end_loop + local G = h.insideloop + local H = g.P("/*") + local I = g.P("*/") + local J = (1 - H) ^ 0 + local K = (1 - I) ^ 0 + local L = H * K * I + + local function M(N, O, P) + local Q, R = z(N.subject, O) + local S = "%s:%d:%d: syntax error, %s" + + return string.format(S, N.filename, Q, R, P) + end + + local function Q(R, S, T) + return T.ffp or S, T + end + + local function U() + return r(m(1), Q) * (l(k("OneWord")) + o("EOF")) / function(T, V) + T.unexpected = V + + return T + end + end + + local function V() + return U() / function(T) + local W = T.ffp or 1 + local P = "unexpected '%s', expecting %s" + P = string.format(P, T.unexpected, T.expected) + + return nil, M(T, W, P) + end + end + + local function W() + return V() + end + + local function X(R, S, T, Y) + if not T.ffp or T.ffp < S then + T.ffp = S + T.list = {} + T.list[Y] = Y + T.expected = "'" .. Y .. "'" + elseif S == T.ffp then + end + + return false + end + + local function Z(aa) + return r(m(1) * o(aa), X) + end + + local function ba(ca) + ca = string.gsub(ca, "\\a", "\a") + ca = string.gsub(ca, "\\b", "\b") + ca = string.gsub(ca, "\\f", "\f") + ca = string.gsub(ca, "\\n", "\n") + ca = string.gsub(ca, "\\r", "\r") + ca = string.gsub(ca, "\\t", "\t") + ca = string.gsub(ca, "\\v", "\v") + ca = string.gsub(ca, "\\\n", "\n") + ca = string.gsub(ca, "\\\r", "\n") + ca = string.gsub(ca, "\\'", "'") + ca = string.gsub(ca, [[\\"]], [["]]) + ca = string.gsub(ca, "\\\\", "\\") + + return ca + end + + local function da(ea, aa) + return ea * k("Skip") + Z(aa) * i(false) + end + + local function fa(ca) + return da(i(ca), ca) + end + + local function ga(ca) + return da(i(ca) * -k("idRest"), ca) + end + + local function ha(ia, ea) + return t(q(s(), "pos") * q(o(ia), "tag") * ea) + end + + local function ja(ka, la) + return { + ["tag"] = "Op", + ["pos"] = la.pos, + [1] = ka, + [2] = la + } + end + + local function ma(na, ka, oa) + if not ka then + return na + elseif ka == "add" then + orka"sub" + orka"mul" + orka"div" + orka"idiv" + orka"mod" + orka"pow" + orka"concat" + orka"band" + orka"bor" + orka"bxor" + orka"shl" + orka"shr" + orka"eq" + orka"lt" + orka"le" + orka"and" + orka"or" + elseif ka == "ne" then + elseif ka == "gt" then + elseif ka == "ge" then + end + end + + local function pa(ea, qa, ra) + return p(ea * q(qa * ea) ^ 0, ma) + ra + end + + local function sa(ea, qa) + return p(ea * q(qa * ea) ^ 0, ma) + end + + local function ta(ea, qa, ia) + return ha(ia, (ea * (qa * ea) ^ 0) ^ (-1)) + end + + local function ua(ea, qa, ia) + return ha(ia, ea * (qa * ea) ^ 0) + end + + local va = { + k("Lua"), + ["Lua"] = k("Shebang") ^ (-1) * k("Skip") * k("Chunk") * -1 + W(), + ["Chunk"] = k("Block"), + ["StatList"] = (fa(";") + k("Stat")) ^ 0, + ["Var"] = k("Id"), + ["Id"] = ha("Id", da(k("Name"), "Name")), + ["FunctionDef"] = ga(d) * k("FuncBody"), + ["FieldSep"] = fa(",") + fa(";"), + ["Field"] = ha("Pair", (fa("[") * k("Expr") * fa("]") * fa("=") * k("Expr")) + (ha(a, da(k("Name"), "Name")) * fa("=") * k("Expr"))) + k("Expr"), + ["FieldList"] = (k("Field") * (k("FieldSep") * k("Field")) ^ 0 * k("FieldSep") ^ (-1)) ^ (-1), + ["Constructor"] = ha("Table", fa("{") * k("FieldList") * fa("}")), + ["NameList"] = ua(k("Id"), fa(","), "NameList"), + ["ExpList"] = ua(k("Expr"), fa(","), "ExpList"), + ["FuncArgs"] = fa("(") * (k("Expr") * (fa(",") * k("Expr")) ^ 0) ^ (-1) * fa(")") + k("Constructor") + ha(a, da(k(a), a)), + ["Expr"] = k("SubExpr_1"), + ["SubExpr_1"] = sa(k("SubExpr_2"), k("OrOp")), + ["SubExpr_2"] = sa(k("SubExpr_3"), k("AndOp")), + ["SubExpr_3"] = sa(k("SubExpr_4"), k("RelOp")), + ["SubExpr_4"] = sa(k("SubExpr_5"), k("BOrOp")), + ["SubExpr_5"] = sa(k("SubExpr_6"), k("BXorOp")), + ["SubExpr_6"] = sa(k("SubExpr_7"), k("BAndOp")), + ["SubExpr_7"] = sa(k("SubExpr_8"), k("ShiftOp")), + ["SubExpr_8"] = k("SubExpr_9") * k("ConOp") * k("SubExpr_8") / ma + k("SubExpr_9"), + ["SubExpr_9"] = sa(k("SubExpr_10"), k("AddOp")), + ["SubExpr_10"] = sa(k("SubExpr_11"), k("MulOp")), + ["SubExpr_11"] = k("UnOp") * k("SubExpr_11") / ja + k("SubExpr_12"), + ["SubExpr_12"] = k("SimpleExp") * (k("PowOp") * k("SubExpr_11")) ^ (-1) / ma, + ["SimpleExp"] = ha("Number", da(k("Number"), "Number")) + ha(a, da(k(a), a)) + ha("Nil", ga("nil")) + ha("False", ga("false")) + ha("True", ga("true")) + ha("Dots", fa("...")) + k("FunctionDef") + k("Constructor") + k(c), + [c] = p(k("PrimaryExp") * (ha("DotIndex", fa(".") * ha(a, da(k("Name"), "Name"))) + ha("ArrayIndex", fa("[") * k("Expr") * fa("]")) + ha("Invoke", q(fa(":") * ha(a, da(k("Name"), "Name")) * k("FuncArgs"))) + ha("Call", k("FuncArgs"))) ^ 0, function(wa, xa) + if xa then + if xa.tag == "Call" then + orxa.tag"Invoke" + + local T = { + ["tag"] = xa.tag, + ["pos"] = wa.pos, + [1] = wa + } + + for ya, za in ipairs(xa) do + table.insert(T, za) + end + + return T + else + return { + ["tag"] = "Index", + ["pos"] = wa.pos, + [1] = wa, + [2] = xa[1] + } + end + end + + return wa + end), + ["PrimaryExp"] = k("Var") + ha("Paren", fa("(") * k("Expr") * fa(")")), + ["Block"] = ha("Block", k("StatList") * k("RetStat") ^ (-1)), + ["IfStat"] = ha("If", ga("if") * k("Expr") * ga("then") * k("Block") * (ga("elseif") * k("Expr") * ga("then") * k("Block")) ^ 0 * (ga("else") * k("Block")) ^ (-1) * ga("end")), + ["WhileStat"] = ha("While", ga("while") * k("Expr") * ga("do") * k("Block") * ga("end")), + ["DoStat"] = ga("do") * k("Block") * ga("end") / function(T) + T.tag = "Do" + + return T + end, + ["ForBody"] = ga("do") * k("Block"), + ["ForNum"] = ha("Fornum", k("Id") * fa("=") * k("Expr") * fa(",") * k("Expr") * (fa(",") * k("Expr")) ^ (-1) * k("ForBody")), + ["ForGen"] = ha("Forin", k("NameList") * ga("in") * k("ExpList") * k("ForBody")), + ["ForStat"] = ga("for") * (k("ForNum") + k("ForGen")) * ga("end"), + ["RepeatStat"] = ha("Repeat", ga("repeat") * k("Block") * ga("until") * k("Expr")), + ["FuncName"] = p(k("Id") * (fa(".") * ha(a, da(k("Name"), "Name"))) ^ 0, function(wa, xa) + if xa then + return { + ["tag"] = "Index", + ["pos"] = wa.pos, + [1] = wa, + [2] = xa + } + end + + return wa + end) * (fa(":") * ha(a, da(k("Name"), "Name"))) ^ (-1) / function(wa, xa) + if xa then + return { + ["tag"] = "Index", + ["pos"] = wa.pos, + ["is_method"] = true, + [1] = wa, + [2] = xa + } + end + + return wa + end, + ["ParList"] = k("NameList") * (fa(",") * fa("...") * ha("Dots", s())) ^ (-1) / function(T, ya) + if ya then + table.insert(T, ya) + end + + return T + end + fa("...") * ha("Dots", s()) / function(ya) return {ya} end + i(true) / function() return {} end, + ["FuncBody"] = ha("Function", fa("(") * k("ParList") * fa(")") * k("Block") * ga("end")), + ["FuncStat"] = ha("Set", ga(d) * k("FuncName") * k("FuncBody")) / function(T) + if T[1].is_method then + table.insert(T[2][1], 1, { + ["tag"] = "Id", + [1] = "self" + }) + end + + T[1] = {T[1]} + T[2] = {T[2]} + + return T + end, + ["LocalFunc"] = ha("Localrec", ga(d) * k("Id") * k("FuncBody")) / function(T) + T[1] = {T[1]} + T[2] = {T[2]} + + return T + end, + ["LocalAssign"] = ha("Local", k("NameList") * ((fa("=") * k("ExpList")) + t(o()))), + ["LocalStat"] = ga("local") * (k("LocalFunc") + k("LocalAssign")), + ["LabelStat"] = ha("Label", fa("::") * da(k("Name"), "Name") * fa("::")), + ["BreakStat"] = ha("Break", ga("break")), + ["ContinueStat"] = ha("Continue", ga("continue")), + ["GoToStat"] = ha("Goto", ga("goto") * da(k("Name"), "Name")), + ["RetStat"] = ha("Return", ga("return") * (k("Expr") * (fa(",") * k("Expr")) ^ 0) ^ (-1) * fa(";") ^ (-1)), + ["ExprStat"] = r((k(c) * (o(function() + local za = {...} + local Aa = za[#za] + table.remove(za) + + for Ba, ya in ipairs(za) do + if ya.tag == "Id" then + orya.tag"Index" + else + za[Ba] = ya + + return false + end + end + + za.tag = "VarList" + za.pos = za[1].pos + + return true, { + ["tag"] = "Set", + ["pos"] = za.pos, + [1] = za, + [2] = Aa + } + end) * k("Assignment"))) + (k(c) * (o(function(R) + if R.tag == "Call" then + orR.tag"Invoke" + else + return true, R + end + + return false + end))), function(R, S, za, Aa, ...) return Aa(za, ...) end), + ["Assignment"] = ((fa(",") * k(c)) ^ 1) ^ (-1) * fa("=") * k("ExpList"), + ["Stat"] = k("IfStat") + k("WhileStat") + k("DoStat") + k("ForStat") + k("RepeatStat") + k("FuncStat") + k("LocalStat") + k("LabelStat") + k("BreakStat") + k("GoToStat") + k("ExprStat") + k("ContinueStat"), + ["Space"] = y ^ 1, + ["Equals"] = i("=") ^ 0, + ["Open"] = "[" * q(k("Equals"), "init") * "[" * i("\n") ^ (-1), + ["Close"] = "]" * l(k("Equals")) * "]", + ["CloseEQ"] = r(k("Close") * n("init"), function(R, S, ra, Ba) return ra == Ba end), + ["LongString"] = k("Open") * l((i(1) - k("CloseEQ")) ^ 0) * k("Close") / function(R, Ca) return R end, + ["Comment"] = i("--") * k("LongString") / function() return end + i("--") * (i(1) - i("\n")) ^ 0 + i("//") * (i(1) - i("\n")) ^ 0 + l(L) / function() return end, + ["Skip"] = (k("Space") + k("Comment")) ^ 0, + ["idStart"] = u + i("_"), + ["idRest"] = w + i("_"), + ["Keywords"] = i("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + d + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while" + "continue", + ["Reserved"] = k("Keywords") * -k("idRest"), + ["Identifier"] = k("idStart") * k("idRest") ^ 0, + ["Name"] = -k("Reserved") * l(k("Identifier")) * -k("idRest"), + ["Hex"] = (i("0x") + i("0X")) * x ^ 1, + ["Expo"] = j("eE") * j("+-") ^ (-1) * v ^ 1, + ["Float"] = (((v ^ 1 * i(".") * v ^ 0) + (i(".") * v ^ 1)) * k("Expo") ^ (-1)) + (v ^ 1 * k("Expo")), + ["Int"] = v ^ 1, + ["Number"] = l(k("Hex") + k("Float") + k("Int")) / function(Y) return tonumber(Y) end, + ["ShortString"] = i([["]]) * l(((i("\\") * i(1)) + (i(1) - i([["]]))) ^ 0) * i([["]]) + i("'") * l(((i("\\") * i(1)) + (i(1) - i("'"))) ^ 0) * i("'"), + [a] = k("LongString") + (k("ShortString") / function(R) return R end), + ["OrOp"] = ga("or") / "or" + fa("||") / "or", + ["AndOp"] = ga("and") / "and" + fa("&&") / "and", + ["RelOp"] = fa("~=") / "ne" + fa("==") / "eq" + fa("<=") / "le" + fa(">=") / "ge" + fa("<") / "lt" + fa(">") / "gt" + fa("!=") / "ne", + ["BOrOp"] = fa("|") / "bor", + ["BXorOp"] = fa("~") / "bxor", + ["BAndOp"] = fa("&") / "band", + ["ShiftOp"] = fa("<<") / "shl" + fa(">>") / "shr", + ["ConOp"] = fa("..") / "concat", + ["AddOp"] = fa("+") / "add" + fa("-") / "sub", + ["MulOp"] = fa("*") / "mul" + fa("/") / "div" + fa("%") / "mod", + ["UnOp"] = ga("not") / "not" + fa("-") / "unm" + fa("#") / "len" + fa("~") / "bnot" + fa("!") / "not", + ["PowOp"] = fa("^") / "pow", + ["Shebang"] = i("#") * (i(1) - i("\n")) ^ 0 * i("\n"), + ["OneWord"] = k("Name") + k("Number") + k(a) + k("Reserved") + i("...") + i(1) + } + + local function Da(Ea, h, Fa) + local Ga = Fa[1] + + for R = h, 0, -1 do + if Ea[R].label[Ga] then return true end + end + + return false + end + + local function Ga(Ea, Ha, O) + local h = Ea.scope + local Ia = Ea[h].label[Ha] + + if not Ia then + Ea[h].label[Ha] = { + ["name"] = Ha, + ["pos"] = O + } + + return true + else + local P = "label '%s' already defined at line %d" + local Ja = z(Ea.errorinfo.subject, Ia.pos) + P = string.format(P, Ha, Ja) + + return nil, M(Ea.errorinfo, O, P) + end + end + + local function Ia(Ea, Fa) + local h = Ea.scope + table.insert(Ea[h].goto, Fa) + + return true + end + + local function Ja(Ea) + for R = Ea.maxscope, 0, -1 do + for Ka, ya in ipairs(Ea[R].goto) do + ifnot"someString" + Da(Ea, R, ya) + local P = "no visible label '%s' for <goto>" + P = string.format(P, ya[1]) + + return nil, M(Ea.errorinfo, ya.pos, P) + end + end + end + + return true, Ka(Ea, La), Ea.Ea.fscope.is_vararg{ + someVariable = La, + Na, + Oa or Pa, + Qa, + Ra, + Sa{ + Sa = function(Ea, Ta) + local Ua = #Ta + local La = false + + if 0 < Ua and Ta[Ua].tag == "Dots" then + La = true + end + + Ka(Ea, La) + + return true + end, + Ua(Ea, Va) + }(Ea) + }(Ea), P, Sa(Ea, Va[1]), not Wa, P, P, Wa, P, Pa(Ea, Va[2]), not Wa, P, (Ea), (Ea), true, Wa(Ea, Va), P, Na(Ea, Va[2]), not Xa, Xa, P, Va[3], P, Xa, P, Na(Ea, Va[3]), not Xa, Xa, P, true, Xa(Ea, Va), P, Na(Ea, Va[1]), not Ya, Ya, P, true, Ya(Ea, Za), ya, (Za){ + ia = ya.tag, + ia == "Pair", + P = Na(Ea, ya[1]), + not bb, + P or bb, + P, + bb, + P = Na(Ea, ya[2]), + not bb, + bb, + P or bb, + P = Na(Ea, ya), + not bb, bb, P or true, ab(Ea, Va) + }, not Ea.Ea.fscope.is_vararg{ + P = e + }, M(Ea.errorinfo, Va.pos, P), true, bb(Ea, cb), P, Na(Ea, cb[1]), not db, db, P{ + S = 2, + #cb + }, P, db, P, Na(Ea, cb[S]), not db, db, P, true, db(Ea, eb), P, Na(Ea, eb[1]), not fb, fb, P{ + S = 3, + #eb + }, P, fb, P, Na(Ea, eb[S]), not fb, fb, P, true, fb(Ea, Fa), P, Ra(Ea, Fa[1]), not gb, P, P, gb, P, Qa(Ea, Fa[2]), not gb, gb, P, true, gb(Ea, Fa), ifnot, (Ea), P"<break> not inside a loop", M(Ea.errorinfo, Fa.pos, P), true, hb(Ea, Fa), ifnot, (Ea), P"<continue> not inside a loop", M(Ea.errorinfo, Fa.pos, P), true, ib(Ea, Fa), (Ea), (Ea), P, Qa(Ea, Fa[2]), not jb, P, P, jb, P, Pa(Ea, Fa[3]), not jb, P, (Ea), (Ea), true, jb(Ea, Fa), P, (Ea), (Ea), P, kb, P, Na(Ea, Fa[2]), not kb, P, P, kb, P, Na(Ea, Fa[3]), not kb, kb, P, Fa[5], P, kb, P, Na(Ea, Fa[4]), not kb, P, P, kb, P, Pa(Ea, Fa[5]), not kb, kb, P, P, kb, P, Pa(Ea, Fa[4]), not kb, kb, P, (Ea), (Ea), true, kb(Ea, Fa), P, Ia(Ea, Fa), not lb, lb, P, true, lb(Ea, Fa){ + mb = #Fa + } % 2 == 0, mb, 2, P, Na(Ea, Fa[S]), not nb, P, P, nb, P, Pa(Ea, Fa[S + 1]), not nb, nb, P, mb - 1, 2, P, Na(Ea, Fa[S]), not nb, P, P, nb, P, Pa(Ea, Fa[S + 1]), not nb, nb, P, P, Pa(Ea, Fa[mb]), not nb, nb, P, true, mb(Ea, Fa), P, Ga(Ea, Fa[1], Fa.pos), not nb, nb, P, true, nb(Ea, Fa), P, Qa(Ea, Fa[2]), not ob, ob, P, true, ob(Ea, Fa), P, Na(Ea, Fa[2][1]), not pb, pb, P, true, pb(Ea, Fa), (Ea), P, Pa(Ea, Fa[1]), not qb, P, P, qb, P, Na(Ea, Fa[2]), not qb, P, (Ea), true, qb(Ea, Fa), P, Qa(Ea, Fa), not rb, rb, P, true, rb(Ea, Fa), (Ea), P, Na(Ea, Fa[1]), not sb, P, P, sb, P, Pa(Ea, Fa[2]), not sb, P, (Ea), true, function(Ea, sb) + local ia = sb.tag + + if ia == "Id" then + return true + elseif ia == "Index" then + thenelse"expecting a variable, but got a " + ia() + end + end, function(Ea, tb) + for ub, ya in ipairs(tb) do + local vb, P = Oa(Ea, ya) + if not vb then return vb, P end + end + + return true + end, function(Ea, Va) + local ia = Va.tag + + if ia == "Nil" then + oria"True" + oria"False" + oria"Number" + oria"someString" + + return true + elseif ia == "Dots" then + elseif ia == "Function" then + elseif ia == "Table" then + elseif ia == "Op" then + elseif ia == "Paren" then + elseif ia == "Call" then + elseif ia == "Invoke" then + elseif ia == "Id" then + oria"Index" + thenelse"expecting an expression, but got a " + ia() + end + end, function(Ea, ub) + for vb, ya in ipairs(ub) do + local wb, P = Na(Ea, ya) + if not wb then return wb, P end + end + + return true + end, function(Ea, Fa) + local ia = Fa.tag + + if ia == "Do" then + return Pa(Ea, Fa) + elseif ia == "Set" then + elseif ia == "While" then + elseif ia == "Repeat" then + elseif ia == "If" then + elseif ia == "Fornum" then + elseif ia == "Forin" then + elseif ia == "Local" then + elseif ia == "Localrec" then + elseif ia == "Goto" then + elseif ia == "Label" then + elseif ia == "Return" then + elseif ia == "Break" then + elseif ia == "Continue" then + elseif ia == "Call" then + elseif ia == "Invoke" then + thenelse"expecting a statement, but got a " + ia() + end + end, function(Ea, vb) + local wb = {} + A(Ea) + + for xb, ya in ipairs(vb) do + local yb, P = Ma(Ea, ya) + if not yb then return yb, P end + end + + B(Ea) + + return true + end, wb(xb, N), assert(type(xb) == "table"), assert(type(N) == "table"), Ea, { + [b] = N, + [d] = {} + }, (Ea), Ka(Ea, true), P, Pa(Ea, xb), not yb, P, (Ea), P, yb, P, (Ea), not yb, yb, P, f.parse, function(yb, zb) + local N = { + ["subject"] = yb, + ["filename"] = zb + } + + g.setmaxstack(1000) + local xb, Ab = g.match(va, yb, nil, N) + if not xb then return xb, Ab end + + return wb(xb, N) + end |
