Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://angg.twu.net/LUA/Arith6.lua.html -- http://angg.twu.net/LUA/Arith6.lua -- (find-angg "LUA/Arith6.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- (defun a () (interactive) (find-angg "LUA/Arith6.lua")) -- (defun a6 () (interactive) (find-angg "LUA/Arith6.lua")) -- (defun a5 () (interactive) (find-angg "LUA/Arith5.lua")) -- (defun a4 () (interactive) (find-angg "LUA/Arith4.lua")) -- (find-angg "LUA/Lazy5.lua" "Lazy") -- (find-angg "LUA/Lazy5.lua" "Lazy" "totree =") -- (find-books "__comp/__comp.el" "aho" "left-associative") -- «.BinOps» (to "BinOps") -- «.BinExpr» (to "BinExpr") -- «.BinExpr-tests» (to "BinExpr-tests") -- «.Parenthesize» (to "Parenthesize") -- «.defs_0» (to "defs_0") -- (find-es "lpeg" "lpeg-quickref") -- (find-es "lpeg" "globals") require "lpeg" B,C,P,R,S,V = lpeg.B,lpeg.C,lpeg.P,lpeg.R,lpeg.S,lpeg.V Cb,Cc,Cf,Cg = lpeg.Cb,lpeg.Cc,lpeg.Cf,lpeg.Cg Cp,Cs,Ct = lpeg.Cp,lpeg.Cs,lpeg.Ct Carg,Cmt = lpeg.Carg,lpeg.Cmt lpeg_methods = getmetatable(P("")).__index -- «BinOps» (to ".BinOps") -- BinOp = Class { type = "BinOp", __tostring = mytostring, __index = { }, } BinOps = Class { type = "BinOps", new = function () return BinOps({ _ = {} }) end, __tostring = function (o) return mytostringv(o._) end, __index = { has = function (bops, name) return bops._[name] end, get = function (bops, name) return bops._[name] end, add = function (bops, ...) local A = {...} for i=1,#A-2,3 do local lbp,rbp,names = A[i],A[i+1],A[i+2] for _,name in ipairs(split(names)) do bops._[name] = BinOp {name=name, lbp=lbp, rbp=rbp} end end return bops end, }, } binops = BinOps.new() binops:add(10, 11, "+ -", 20, 21, "* /", 31, 30, "^") -- «BinExpr» (to ".BinExpr") -- BinExpr = Class { type = "BinExpr", from = function (a, op, b) return BinExpr {[0]=op, a, b} end is = function (o) return otype(o) == "BinExpr" end, isl = function (o) return BinExpr.is(o) and BinExpr.is(o[1]) end, isr = function (o) return BinExpr.is(o) and BinExpr.is(o[2]) end, isl_paren = function (o) if not BinExpr.isl(o) then return false end local rbp,lbp = o[1]:rbp(), o:lbp() return rbp < lbp end, isr_paren = function (o) if not BinExpr.isr(o) then return false end local rbp,lbp = o:rbp(), o[2]:lbp() return lbp < rbp end, __tostring = function (bex) local l,r = tostring(bex[1]), tostring(bex[2]) if bex:isl_paren() then l = "("..l..")" end if bex:isr_paren() then r = "("..r..")" end return format("%s %s %s", l, bex[0], r) end, __index = { lbp = function (bex) return binops:get(bex[0]).lbp end, rbp = function (bex) return binops:get(bex[0]).rbp end, isl = function (bex) return BinExpr.isl(bex) end, isr = function (bex) return BinExpr.isr(bex) end, isl_paren = function (bex) return BinExpr.isl_paren(bex) end, isr_paren = function (bex) return BinExpr.isr_paren(bex) end, }, } -- «BinExpr-tests» (to ".BinExpr-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Arith6.lua" = binops be = function (a, op, b) return BinExpr {[0]=op, a, b} end foo = be(22, "+", 33) = BinExpr.is(foo) = BinExpr.is(22) = BinExpr.isl(foo) = BinExpr.isr(foo) = foo = be(44, "*", foo) = be(be(22, "+", 33), "*", be(44, "^", 55)) = be(be(22, "^", 33), "*", be(44, "+", 55)) = be(be(22, "-", 33), "-", be(44, "-", 55)) run_my_repl_now() dg = dgis = dg = dg[7] = dg[7]:info() --]] s = S(" \t\n")^0 num = C(R("09")^1) Tree = Class { type = "Tree", __tostring = function (o) return tostring(SynTree.from(o)) end, __index = { }, } Tok = Class { type = "Tok", anyof = function (str) local plus = function (a, b) return a+b end return C(foldl1(plus, map(P, split(str)))) end, __index = { }, } Assoc = Class { type = "Assoc", afoldl = function (f, A) local o = A[1] for i=3,#A,2 do o = f(o, A[i-1], A[i]) end return o end, afoldr = function (f, A) local o = A[#A] for i=#A-2,1,-2 do o = f(A[i], A[i+1], o) end return o end, mktr = function (a, op, b) return BinExpr {[0]=op, a, b} end, afoldltr = function (A) return Assoc.afoldl(Assoc.mktr, A) end, afoldrtr = function (A) return Assoc.afoldr(Assoc.mktr, A) end, list = function (e, op) return Ct(e*(op*e)^0) end, left = function (e, op) return Assoc.list(e, op) / Assoc.afoldltr end, right = function (e, op) return Assoc.list(e, op) / Assoc.afoldrtr end, __index = { }, } istable = function (o) return type(o) == "table" end --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Arith6.lua" f = function (a, b) return format("(%s,%s)", a, b) end af = function (a,op,b) return format("(%s %s %s)", a, op, b) end = Assoc.afoldl(af, {2, "+", 4, "*", 6, "/", 7}) = Assoc.afoldr(af, {2, "+", 4, "*", 6, "/", 7}) op_exp = Tok.anyof("^") op_mul = Tok.anyof("* /") op_add = Tok.anyof("+ -") expr_exp = Assoc.right(num, op_exp) expr_mul = Assoc.left(expr_exp, op_mul) expr_add = Assoc.left(expr_mul, op_add) = Tree(expr_exp:match("22^33^44^55")) = Tree(expr_add:match("22^33^44^55-66-77")) = expr_add:match("22^33^44^55-66-77") expr_all = lpeg.P{ "expr_add", expr_basic = num + "(" * V"expr_add" * ")", expr_exp = Assoc.right(V"expr_basic", op_exp), expr_mul = Assoc.left (V"expr_exp", op_mul), expr_add = Assoc.left (V"expr_mul", op_add), } = Tree(expr_add:match("22^33+44*(55-66-77)^88^99")) = Tree(expr_all:match("22^33+44*(55-66-77)^88^99")) = expr_all:match("22^33+44*(55-66-77)^88^99") --]] -- «Parenthesize» (to ".Parenthesize") Parenthesize = Class { type = "Parenthesize", new = function () return Parenthesize {binops={}} end, __tostring = function (pth) return mytostringv(pth.binops) end, __index = { binops = {}, addbinops = function (pth, A) for i=1,#A-2,3 do local lbp,rbp,ops = A[i], A[i+1], A[i+2] for _,op in ipairs(split(ops)) do pth.binops[op] = {lbp=lbp, rbp=rbp} end end return pth end, isbin = function (pth, o) return type(o) == "table" and #o == 2 and o[0] and pth.binops[o[0]] end, isbinlbin = function (pth, o) return pth:isbin(o) and pth:isbin(o[1]) end, isbinrbin = function (pth, o) return pth:isbin(o) and pth:isbin(o[2]) end, lbp = function (pth, o) return pth:isbin(o) and pth.binops[o[0]].lbp end, rbp = function (pth, o) return pth:isbin(o) and pth.binops[o[0]].rbp end, lparen = function (pth, o) if pth:isbin(o) then return pth:isbin(o[1]) and pth:rbp(o[1]) < pth:lbp(o) end end, rparen = function (pth, o) if pth:isbin(o) then return pth:isbin(o[2]) and pth:lbp(o[2]) < pth:rbp(o) end end, tos = function (pth, o) if type(o) == "number" then return tostring(o) end if type(o) == "string" then return o end if type(o) == "table" then if pth:isbin(o) then local strl,strr = pth:tos(o[1]), pth:tos(o[2]) if pth:lparen(o) then strl = "("..strl..")" end if pth:rparen(o) then strr = "("..strr..")" end return format("%s %s %s", strl, o[0], strr) end error("a") end error("b") end, }, } -- «defs_0» (to ".defs_0") defs_0 = function () op_exp = Tok.anyof("^") op_mul = Tok.anyof("* /") op_add = Tok.anyof("+ -") -- pth = Parenthesize.new():addbinops({ 10, 11, "+ -", 20, 21, "* /", 31, 30, "^", }) -- expr_0 = lpeg.P{ "expr_add", expr_basic = num + "(" * V"expr_add" * ")", expr_exp = Assoc.right(V"expr_basic", op_exp), expr_mul = Assoc.left (V"expr_exp", op_mul), expr_add = Assoc.left (V"expr_mul", op_add), } end --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Arith6.lua" defs_0() = pth foo = expr_0:match("22^33+44*(55-66-77)^88^99") foo = expr_0:match("(22-33)-(44-55)") = Tree(foo) = pth:tos(foo) foo = expr_0:match("(22^33)^(44^55)") = Tree(foo) = pth:tos(foo) foo = expr_0:match("(22+33)*(44^55)") = Tree(foo) = pth:tos(foo) = pth:tos(22) = pth:tos("bla") -- (find-anggfile "OCAML/calc0.ml") --]] -- Local Variables: -- coding: utf-8-unix -- End: