|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LUA/PegDebug1.lua.html
-- http://anggtwu.net/LUA/PegDebug1.lua
-- (find-angg "LUA/PegDebug1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun e () (interactive) (find-angg "LUA/PegDebug1.lua"))
-- (find-es "lpeg" "pegdebug0")
-- (find-es "lpeg" "pegdebug")
-- Moved to: (find-angg "LUA/Gram2.lua" "LpegDebug")
require "lpeg" -- (find-es "lpeg" "globals")
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
pegdebug = {
_NAME = "pegdebug",
_VERSION = 0.41,
_COPYRIGHT = "Paul Kulchenko",
_DESCRIPTION = "Debugger for LPeg expressions and processing",
}
function pegdebug.trace(grammar, opts)
opts = opts or {}
local function line(s) return (string.format("%q", s):gsub("\\\n", "\\n")) end
local function pretty(...)
-- if serpent then return serpent({...}, {comment = false}):sub(2,-2) end
local res = {}
for i = 1, select('#', ...) do
local v = select(i, ...)
local tv = type(v)
res[i] = tv == 'number' and v or tv == 'string' and line(v) or tostring(v)
end
return table.concat(res, ", ")
end
local level = 0
local start = {}
local print = print
if type(opts.out) == 'table' then
print = function(...) table.insert(opts.out, table.concat({...}, "\t")) end
end
for k, p in pairs(grammar) do
local enter = Cmt(P(true), function(s, p, ...)
start[level] = p
if opts['+'] ~= false then
print((" "):rep(level).."+", k, p, line(s:sub(p,p)))
end
level = level + 1
return true
end)
local leave = Cmt(P(true), function(s, p, ...)
level = level - 1
if opts['-'] ~= false then
print((" "):rep(level).."-", k, p)
end
return true
end) * (P(1) - P(1))
local eq = Cmt(P(true), function(s, p, ...)
level = level - 1
if opts['='] ~= false then
print((" "):rep(level).."=", k, start[level]..'-'..(p-1), line(s:sub(start[level],p-1)))
end
return true
end)
if k ~= 1 and (not opts.only or opts.only[k]) then
if opts['/'] ~= false
and (type(opts['/']) ~= 'table' or opts['/'][k] ~= false) then
-- Cp() is needed to only get captures (and not the whole match)
p = Cp() * p / function(pos, ...)
print((" "):rep(level).."/", k, pos, select('#', ...), pretty(...))
return ...
end
end
grammar[k] = enter * p * eq + leave
end
end
return grammar
end
-- return pegdebug
LpegDebug = Class {
type = "LpegDebug",
from = function (name)
return LpegDebug {name=name}
end,
__tostring = function (lpd) return mytostringp(lpd) end,
__index = {
subst = function (lpd, fmt, pos)
local name = lpd.name
local A = {name=name, pos=pos}
return (fmt:gsub("<(.-)>", A))
end,
f = function (lpd, fmt)
return function (subj,pos,...)
printf(lpd:subst(fmt, pos))
return pos,...
end
end,
cmt0 = function (lpd, fmt, pat) return pat:Cmt(lpd:f(fmt)) end,
cmtt = function (lpd, fmt) return lpd:cmt0(fmt, lpeg.P(true)) end,
pbeg = function (lpd) return lpd:cmtt("(<name>:<pos>\n") end,
pmid = function (lpd) return lpd:cmtt(" <name>:<pos>\n") end,
pend = function (lpd) return lpd:cmtt(" <name>:<pos>)\n") end,
pfail = function (lpd) return lpd:cmtt(" <name>:fail)\n") end,
dbg = function (lpd, pat)
return lpd:pbeg()*pat*lpd:pend()
+ lpd:pfail()*P(false)
end,
},
}
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "PegDebug1.lua"
lpd = LpegDebug.from("A")
= lpd
= lpd:subst("foo")
= lpd:subst("foo<name>")
= lpd:subst("foo<name><pos>.", 42)
pa = P"aa":Cs()
pb = P"bb":Cs()
pt = P(true)
pbeg = lpd:pbeg()
pmid = lpd:pmid()
pend = lpd:pend()
pfail = lpd:pfail()
pbeg = lpd:pbeg()
pbeg = lpd:cmtt("(<name>:<pos>\n")
pmid = lpd:cmtt(" <name>:<pos>\n")
pend = lpd:cmtt(" <name>:<pos>)\n")
= (pa*pb) : match("aabbcc")
= (pbeg*pa*pmid*pb*pend) : match("aabbcc")
= lpd:dbg(pa*pb) : match("aabbcc")
= lpd:dbg(pa*pb) : match("aacc")
= (pa*pb) : match("aacc")
ldebug = function (name, pat) return LpegDebug.from(name):dbg(pat) end
= ldebug("ab", pa*pb) : match("aabbcc")
= ldebug("ab", pa*pb) : match("aac")
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: