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: