Kill the |toSource| method, introduce the |output| option

Before this commit, |PEG.buildParser| always returned a parser object.
The only way to get its source code was to call the |toSource| method on
it. While this method worked for parsers produced by |PEG.buildParser|
directly, it didn't work for parsers instantiated by executing their
source code. In other words, it was unreliable.

This commit remvoes the |toSource| method on generated parsers and
introduces a new |output| option to |PEG.buildParser|. It allows callers
to specify whether they want to get back the parser object
(|options.output === "parser"|) or its source code (|options.output ===
"source"|). This is much better and more reliable API.
redux
David Majda 12 years ago
parent 3629d880d3
commit 05a6bad989

@ -94,11 +94,10 @@ a parameter:
var parser = PEG.buildParser("start = ('a' / 'b')+");
The method will return generated parser object or throw an exception if the
grammar is invalid. The exception will contain `message` property with more
details about the error.
To get parsers source code, call the `toSource` method on the parser.
The method will return generated parser object or its source code as a string
(depending on the value of the `output` option — see below). It will throw an
exception if the grammar is invalid. The exception will contain `message`
property with more details about the error.
You can tweak the generated parser by passing a second parameter with an options
object to `PEG.buildParser`. The following options are supported:
@ -111,6 +110,9 @@ object to `PEG.buildParser`. The following options are supported:
(default: `false`)
* `allowedStartRules` — rules the parser will be allowed to start parsing from
(default: the first rule in the grammar)
* `output` — if set to `"parser"`, the method will return generated parser
object; if set to `"source"`, it will return parser source code as a string
(default: `"parser"`)
Using the Parser
----------------

@ -73,7 +73,8 @@ function readStream(inputStream, callback) {
var exportVar = "module.exports";
var options = {
cache: false,
trackLineAndColumn: false
trackLineAndColumn: false,
output: "source"
};
while (args.length > 0 && isOption(args[0])) {
@ -158,7 +159,7 @@ switch (args.length) {
readStream(inputStream, function(input) {
try {
var parser = PEG.buildParser(input, options);
var source = PEG.buildParser(input, options);
} catch (e) {
if (e.line !== undefined && e.column !== undefined) {
abort(e.line + ":" + e.column + ": " + e.message);
@ -167,7 +168,7 @@ readStream(inputStream, function(input) {
}
}
outputStream.write(exportVar + " = " + parser.toSource() + ";\n");
outputStream.write(exportVar + " = " + source + ";\n");
if (outputStream !== process.stdout) {
outputStream.end();
}

@ -24,16 +24,16 @@ module.exports = {
compile: function(ast, options) {
if (options === undefined) { options = {}; }
var that = this;
var that = this,
output = options.output !== undefined ? options.output : "parser";
utils.each(this.appliedPassNames, function(passName) {
that.passes[passName](ast, options);
});
var source = ast.code;
var result = eval(source);
result._source = source;
return result;
switch (output) {
case "parser": return eval(ast.code);
case "source": return ast.code;
}
}
};

@ -516,10 +516,7 @@ module.exports = function(ast, options) {
' }',
' ',
' return result;',
' },',
' ',
' /* Returns the parser source code. */',
' toSource: function() { return this._source; }',
' }',
' };',
' ',
' /* Thrown when a parser encounters a syntax error. */',

@ -2840,10 +2840,7 @@ module.exports = (function(){
}
return result;
},
/* Returns the parser source code. */
toSource: function() { return this._source; }
}
};
/* Thrown when a parser encounters a syntax error. */

@ -934,6 +934,37 @@ describe("generated parser", function() {
});
});
describe("output", function() {
var grammar = 'start = "a"';
describe("without the |output| option", function() {
it("returns a parser object", function() {
var parser = PEG.buildParser(grammar);
expect(typeof parser).toBe("object");
expect(parser).toParse("a", "a");
});
});
describe("when the |output| option is set to \"parser\"", function() {
it("returns a parser object", function() {
var parser = PEG.buildParser(grammar, { output: "parser" });
expect(typeof parser).toBe("object");
expect(parser).toParse("a", "a");
});
});
describe("when the |output| option is set to \"source\"", function() {
it("returns a parser source code", function() {
var source = PEG.buildParser(grammar, { output: "source" });
expect(typeof source).toBe("string");
expect(eval(source)).toParse("a", "a");
});
});
});
/*
* Following examples are from Wikipedia, see
* http://en.wikipedia.org/w/index.php?title=Parsing_expression_grammar&oldid=335106938.

Loading…
Cancel
Save