Warning: this is an htmlized version! The original is across this link, and the conversion rules are here.
```#!/usr/bin/env lua5.1
-- This file:
-- http://angg.twu.net/LUA/syntrees.lua
-- http://angg.twu.net/LUA/syntrees.lua.html
--  (find-angg        "LUA/syntrees.lua")
-- By Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2014oct09

--           _            _
--  _ __ ___| |_ ___  ___| |_
-- | '__/ _ \ __/ _ \/ __| __|
-- | | |  __/ ||  __/\__ \ |_
-- |_|  \___|\__\___||___/\__|
--
-- (find-es "lua-intro" "lpeg-re-infix-1")
require "re"
g = function (...) return "("..table.concat({...}, " ")..")" end
f = function (...) local A={...}; return #A==1 and A[1] or g(...) end
defs   = { f = f }
c      = function (pat) return re.compile(pat, defs) end
retest = function (p) return function (s) print(re.match(s, c(p))) end end

--  _____         _     _
-- |_   _|__  ___| |_  / |
--   | |/ _ \/ __| __| | |
--   | |  __/\__ \ |_  | |
--   |_|\___||___/\__| |_|
--
retest [[
e <- e3
e3 <- (e2 ({"+"} e2)*) -> f
e2 <- (e1 ({"*"} e1)*) -> f
e1 <- (e0 ({"^"} e0)*) -> f
e0 <- "(" e3 ")" / {[0-9]+}
]] "1*2+3^4*5^6+(7+8)^9"

--> (find-sh "./syntrees.lua")
--> ((1 * 2) + ((3 ^ 4) * (5 ^ 6)) + (7 ^ 8))

--
--   ___  ___   ___
--  / _ \/ _ \ / _ \
-- |  __/ (_) | (_) |
--  \___|\___/ \___/
--
-- From: (find-angg "LUA/lua50init.lua" "eoo")
Class = {
type   = "Class",
__call = function (class, o) return setmetatable(o, class) end,
}
setmetatable(Class, Class)

otype = function (o)  -- works like type, except on my "objects"
local  mt = getmetatable(o)
return mt and mt.type or type(o)
end

--  ____           _
-- |  _ \ ___  ___| |_
-- | |_) / _ \/ __| __|
-- |  _ <  __/ (__| |_
-- |_| \_\___|\___|\__|
--
-- From: (find-angg "LUA/lua50init.lua" "Rect")
Rect = Class {
type    = "Rect",
new     = function (A) return Rect(A or {""}) end,
from    = function (o)
if otype(o) == "Rect" then return o end
return Rect.new(splitlines(tostring(o)))
end,
__index = {
copy = function (rect) return Rect(shallowcopy(rect)) end,
width = function (rect)
local w = 0
for i=1,#rect do w = max(w, #rect[i]) end
return w
end,
replace1 = function (rect, x, y, r, w)
while #rect < y do table.insert(rect, "") end
rect[y] = rect[y]:replace(x, r, w)
end,
replace = function (rect1, x, y, rect2, w)
w = w or rect2:width()
for i=1,#rect2 do
rect1:replace1(x, y, rect2[i], w)
y = y + 1
end
return rect1
end,
-- For syntax trees:
syntree1 = function (rect, op, hchar, vchar)
rect = rect:copy()
op = op or "."
if hchar then
op = op .. string.rep(hchar, rect:width() + 2 - #op)
end
table.insert(rect, 1, vchar or "|")
table.insert(rect, 1, op)
return rect
end,
},
__concat = function (r1, r2)
return Rect.new():replace(0, 1, r1):replace(r1:width(), 1, r2)
end,
__tostring = function (rect)
return table.concat(rect, "\n")
end,
}

--                  _
--  ___ _   _ _ __ | |_ _ __ ___  ___  __ _
-- / __| | | | '_ \| __| '__/ _ \/ _ \/ _` |
-- \__ \ |_| | | | | |_| | |  __/  __/ (_| |
-- |___/\__, |_| |_|\__|_|  \___|\___|\__, |
--      |___/                         |___/
--
-- From: (find-angg "LUA/lua50init.lua" "syntree")
syntreeg = function (...)
local A = {...}
local rf = function (i, op, h)
return Rect.from(A[i]):syntree1(op, h)
end
if #A == 1 then return A[1] end
r = rf(#A)
for i=#A-2,1,-2 do
r = rf(i, A[i+1], "_")..r
end
return r
end

--  _____         _     ____
-- |_   _|__  ___| |_  |___ \
--   | |/ _ \/ __| __|   __) |
--   | |  __/\__ \ |_   / __/
--   |_|\___||___/\__| |_____|
--
-- (find-es "lua-intro" "lpeg-re-infix-1")

g = syntreeg
retest [[
e <- e3
e3 <- (e2 ({"+"} e2)*) -> f
e2 <- (e1 ({"*"} e1)*) -> f
e1 <- (e0 ({"^"} e0)*) -> f
e0 <- "(" e3 ")" / {[0-9]+}
]] "1*2+3^4*5^6+(7+8)^9"

--> +_____+___________.
--  |     |           |
--  *__.  *_____.     ^__.
--  |  |  |     |     |  |
--  1  2  ^__.  ^__.  7  8
--        |  |  |  |
--        3  4  5  6

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

--]]

-- Local Variables:
-- coding: raw-text-unix
-- End:
```