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: