PEG.js is a simple parser generator for JavaScript that produces fast parsers with excellent error reporting. You can use it to process complex data or computer languages and build transformers, interpreters, compilers and other tools easily.
PEG.js offers tracing support to help analyze parser issues with a grammar. The feature is very helpful, but it's not available yet on the version that's published to npm
, it's not well-advertised, and not well-documented. This gist explains how to take advantage of PEG.js tracing support.
When you generate your parser, make sure you supply the trace
option set to true. If using gulp
, do something like this:
var peg = require('gulp-peg');
var paths = {
peg: ['src/**/*.pegjs'],
dist: 'dist'
};
var pegOptions = {
trace: true
};
gulp.task('peg', ['clean'], function() {
return gulp.src(paths.peg)
.pipe(peg(pegOptions))
.pipe(gulp.dest(paths.dist));
});
When calling the parse
function of your parser, provide an argument for your tracer
object:
parser.parse(text, { tracer: { trace: function(evt) {
...
}}});
Trace events objects have the following properties:
{
"type": " (rule.enter | rule.fail | rule.match) ",
"rule": " (the name of the rule being evaluated) ",
"location": {
"start": {
"offset": 0,
"line": 1,
"column": 1
},
"end": {
"offset": 0,
"line": 1,
"column": 1
}
}
}
Want your tracer object to behave like an EventEmitter? Provide a tracer that emits events like this:
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var parser = require('./path-to-parser');
function Tracer() {
EventEmitter.prototype.call(this);
}
inherits(Tracer, EventEmitter);
// tracer instances need to implement a `trace` method for peg
Tracer.prototype.trace = function(evt) {
this.emit('parse', evt);
};
var tracer = new Tracer();
tracer.on('parse', function(evt) {
// do something cool with the parse event
});
parser.parse(text, { tracer: tracer });
Nice example, thanks. It is in fact present in 0.10.0 currently published to NPM, though as you said it's poorly documented, as are all of the error-handling features of PEG.js generally. This is a real shame, because one of the biggest arguments against parser generators in favor of hand-rolling your own RD parser (or combinator based parser, etc) is the difficulty of handling errors, which tends to be far inferior in available tools vs just inserting the handling into your own parsing code....
I was able to get a trace in 0.10 with a parser I built via the command-line tool; just remember to pass the
--trace
flag to enable it(I also stumbled on a
next.pegjs.org
a few weeks ago but it was gone when I looked a few days later. The author seems to be actively working on improvements behind the scenes. Maybe clear docs are coming)