Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://angg.twu.net/LUA/Lpeg1.lua.html
--   http://angg.twu.net/LUA/Lpeg1.lua
--           (find-angg "LUA/Lpeg1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun e () (interactive) (find-angg "LUA/Lpeg1.lua"))

-- (find-es "lpeg" "pegdebug")
Path.prepend("path", "~/usrc/PegDebug/src/?.lua")
lpeg     = require("lpeg")
pegdebug = require("pegdebug")


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

-- (find-angg "LUA/LpegRex1.lua" "rectfromast")
rectfromast = function (o)
    if type(o) == "number" then return Rect.from(o) end
    if type(o) == "string" then return Rect.from(o) end
    if type(o) == "table" then
      local out = rectfromast(o[#o]):syn1()
      for i=#o-2,1,-2 do
        local lowerleft = rectfromast(o[i])
        local left = lowerleft:syn1(o[i+1])
        local left_ = left:pad0(1, left:width()+2, "_")
        out = left_ .. out
      end
      return out
    end
    PP("rectfromast can't handle this", o)
  end

Ast = Class {
  type = "Ast",
  from = function (...) return Ast({...}) end,
  fromsimp = function (...)
      local L = {...}
      if #L == 1 then return L[1] end
      return Ast.from(...)
    end,
  __tostring = function (o) return rectfromast(o):tostring() end,
  __index = {
  },
}

--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Lpeg1.lua"
= Ast.from(2, "+", 4, "-", 6)
= Ast.from(2, "_[_]", 4)
= Ast.fromsimp(2, "+", 4, "-", 6)
= Ast.from    (Ast.from    (2, "+", 4, "-", 6))
= Ast.fromsimp(Ast.fromsimp(2, "+", 4, "-", 6))
= Ast.from    (Ast.from    (2, "+", 4, "-", 6), "*", 3)
= Ast.fromsimp(Ast.fromsimp(2, "+", 4, "-", 6), "*", 3)

--]]

-- (find-es "lpeg" "lpeg-quickref")
pskip  = P(" ")^0
pNum   = (R("09")^0):C() * pskip
plit   = function (str) return P(str)     * pskip end
ptok   = function (str) return P(str):C() * pskip end
passoc = function (pexp, ptok)
    return (pexp * (ptok * pexp)^0) / Ast.fromsimp
  end

pat1 = P {
  "pAdd",
   pAdd   = passoc(V("pMul"), ptok("+") + ptok("-")),
   pMul   = passoc(pNum     , ptok("*") + ptok("/")),
}

pat2_ = {
  "add",
   add    = passoc(V"mul",  ptok("+") + ptok("-")),
   mul    = passoc(V"norp", ptok("*") + ptok("/")),
   norp   = plit("(") * V("add") * plit(")") + pNum,
}
-- pat2_ = pegdebug.trace(pat2_)
pat2 = P(pat2_)

--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Lpeg1.lua"

pMul = passoc(pNum, ptok("*") + ptok("/"))
pAdd = passoc(pMul, ptok("+") + ptok("-"))
= pAdd:match("1*2 + 3 + 4*5*6 + 7")
= pat1:match("1*2 + 3 + 4*5*6 + 7")
= pat2:match("1*2 + 3 + 4*5*6 + 7")
= pat2:match("(1*2 + 3 + 4*5*6 + 7)")
= pat2:match("(1*2 + 3 + 4*5*6 + 7) * 8")
= pat2:match("33")
= pat2:match("(33)")
= pat2:match("(33)")

= pexpr:match("1*2 + 3 + 4*5*6 + 7")
= pexpr:match("1")


--]]








-- Local Variables:
-- coding:  utf-8-unix
-- End: