Skip to content

Commit 477d357

Browse files
committed
Add support for debug mode
1 parent b2aa0e2 commit 477d357

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

README.md

+53
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,59 @@ local ast = { tag = "Array", pos = 1, endpos = 73,
294294
A JSON parser similar to this example can be found in
295295
[parsers/json.lua](https://github.com/edubart/lpegrex/blob/main/parsers/json.lua).
296296

297+
## Debugging rule entry and exit
298+
299+
When prototyping complex grammars you may want to debug the rules that
300+
the parser is trying to match and the ones that were successfully matched.
301+
You can enable LPegRex debug mode for this
302+
by setting `lpegrex.debug = true` globally.
303+
When debug is enabled all compiled grammars will be compiled in debug mode.
304+
305+
When debugging is enabled every attempt to match a rule will print
306+
`ENTER <rulename> (<lineno>:<colno>)` to `io.stderr`,
307+
and every rule successfully matched will print
308+
`LEAVE <rulename> (<lineno>:<colno>)` to `io.stderr`.
309+
Notice that rules failing to match will not print `LEAVE`.
310+
311+
The following is an example of parsing `{"string":` JSON chunk
312+
using the JSON parser shown above with debugging enabled:
313+
314+
```
315+
ENTER Json (1:1)
316+
ENTER SKIP (1:1)
317+
LEAVE SKIP (1:1)
318+
ENTER Object (1:1)
319+
ENTER { (1:1)
320+
ENTER Array (1:1)
321+
ENTER [ (1:1)
322+
ENTER SKIP (1:2)
323+
LEAVE SKIP (1:2)
324+
LEAVE [ (1:2)
325+
ENTER Value (1:2)
326+
ENTER String (1:2)
327+
ENTER Number (1:2)
328+
ENTER Object (1:2)
329+
ENTER { (1:2)
330+
ENTER SKIP (1:3)
331+
LEAVE SKIP (1:3)
332+
LEAVE { (1:3)
333+
ENTER Member (1:3)
334+
ENTER String (1:3)
335+
ENTER SKIP (1:11)
336+
LEAVE SKIP (1:11)
337+
LEAVE String (1:11)
338+
ENTER : (1:11)
339+
ENTER SKIP (1:12)
340+
LEAVE SKIP (1:12)
341+
LEAVE : (1:12)
342+
```
343+
344+
Notice `String` ENTER at `1:3` and LEAVE at `1:11`,
345+
this means that we have matched the rule `String` in that range.
346+
Notice `Number` ENTER at `1:2` while no LEAVE is shown for `Number`,
347+
this means that we attempted to match `Number`
348+
but it failed since no LEAVE was shown afterwards.
349+
297350
## Installing
298351

299352
To use LPegRex you need [LPegLabel](https://github.com/sqmedeiros/lpeglabel)

lpegrex.lua

+17
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,23 @@ local function mkrex()
247247
end
248248
G.TOKEN = TOKEN
249249
end
250+
if lpegrex.debug then
251+
for k, patt in pairs(G) do
252+
if k ~= 1 then
253+
local enter = lpeg.Cmt(lpeg.P(true), function(s, p)
254+
local lineno, colno = lpegrex.calcline(s, p)
255+
io.stderr:write(string.format('ENTER %s (%d:%d)\n', k, lineno, colno))
256+
return true
257+
end)
258+
local leave = lpeg.Cmt(lpeg.P(true), function(s, p)
259+
local lineno, colno = lpegrex.calcline(s, p)
260+
io.stderr:write(string.format('LEAVE %s (%d:%d)\n', k, lineno, colno))
261+
return true
262+
end)
263+
G[k] = enter * patt * leave
264+
end
265+
end
266+
end
250267
-- cleanup grammar context
251268
G, Gkeywords, Gtokens = nil, nil, nil
252269
return l.P(t)

0 commit comments

Comments
 (0)