|
Warning: this is an htmlized version!
The original is here, 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
-- License: GPL3
-- _ _
-- _ __ ___| |_ ___ ___| |_
-- | '__/ _ \ __/ _ \/ __| __|
-- | | | __/ || __/\__ \ |_
-- |_| \___|\__\___||___/\__|
--
-- (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: