Expose the parser object in action/predicate code

The action/predicate code didn't have access to the parser object. This
was mostly a side effect actions/predicates being implemented as nested
functions, in which |this| is a reference to the global object (an ugly
JavaScript quirk). The initializer, being implemented differently, had
access to the parser object via |this|, but this was not documented.

Because having access to the parser object can be useful, this commits
introduces a new |parser| variable which holds a reference to it, is
visible in action/predicate/initializer code, and is properly
documented.

See also:

  https://groups.google.com/forum/#!topic/pegjs/Na7YWnz6Bmg
redux
David Majda 10 years ago
parent c7521fb868
commit 39084496ca

@ -186,9 +186,10 @@ Rules can be preceded by an *initializer* — a piece of JavaScript code in curl
braces (“{” and “}”). This code is executed before the generated parser starts
parsing. All variables and functions defined in the initializer are accessible
in rule actions and semantic predicates. The code inside the initializer can
access options passed to the parser using the `options` variable. Curly braces
in the initializer code must be balanced. Let's look at the example grammar
from above using a simple initializer.
access the parser object using the `parser` variable and options passed to the
parser using the `options` variable. Curly braces in the initializer code must
be balanced. Let's look at the example grammar from above using a simple
initializer.
{
function makeInteger(o) {
@ -321,8 +322,8 @@ the `offset` function. It returns a zero-based character index into the input
string. The code can also access the current line and column using the `line`
and `column` functions. Both return one-based indexes.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
The code inside the predicate can also access the parser object using the
`parser` variable and options passed to the parser using the `options` variable.
Note that curly braces in the predicate code must be balanced.
@ -343,8 +344,8 @@ the `offset` function. It returns a zero-based character index into the input
string. The code can also access the current line and column using the `line`
and `column` functions. Both return one-based indexes.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
The code inside the predicate can also access the parser object using the
`parser` variable and options passed to the parser using the `options` variable.
Note that curly braces in the predicate code must be balanced.
@ -398,8 +399,8 @@ character index into the input string. The code can also access the line and
column at the beginning of the action's expression using the `line` and `column`
functions. Both return one-based indexes.
The code inside the action can also access options passed to the parser using
the `options` variable.
The code inside the action can also access the parser object using the `parser`
variable and options passed to the parser using the `options` variable.
Note that curly braces in the action code must be balanced.

@ -692,6 +692,7 @@ module.exports = function(ast, options) {
'',
' function peg$parse(input) {',
' var options = arguments.length > 1 ? arguments[1] : {},',
' parser = this,',
'',
' peg$FAILED = {},',
''

@ -26,6 +26,7 @@ module.exports = (function() {
function peg$parse(input) {
var options = arguments.length > 1 ? arguments[1] : {},
parser = this,
peg$FAILED = {},

@ -211,6 +211,15 @@ describe("generated parser", function() {
expect(parser).toParse("a", [1, 1]);
});
it("can use the |parser| variable to access the parser object", function() {
var parser = PEG.buildParser([
'{ var result = parser; }',
'start = "a" { return result; }'
].join("\n"), options);
expect(parser).toParse("a", parser);
});
it("can use options passed to the parser", function() {
var parser = PEG.buildParser([
'{ var result = options; }',
@ -382,6 +391,15 @@ describe("generated parser", function() {
expect(parser).toParse("a", 42);
});
it("can use the |parser| variable to access the parser object", function() {
var parser = PEG.buildParser(
'start = "a" { return parser; }',
options
);
expect(parser).toParse("a", parser);
});
it("can use options passed to the parser", function() {
var parser = PEG.buildParser(
'start = "a" { return options; }',
@ -546,6 +564,15 @@ describe("generated parser", function() {
expect(parser).toParse("a", ["a", undefined]);
});
it("can use the |parser| variable to access the parser object", function() {
var parser = PEG.buildParser([
'{ var result; }',
'start = "a" &{ result = parser; return true; } { return result; }'
].join("\n"), options);
expect(parser).toParse("a", parser);
});
it("can use options passed to the parser", function() {
var parser = PEG.buildParser([
'{ var result; }',
@ -637,6 +664,15 @@ describe("generated parser", function() {
expect(parser).toParse("a", ["a", undefined]);
});
it("can use the |parser| variable to access the parser object", function() {
var parser = PEG.buildParser([
'{ var result; }',
'start = "a" !{ result = parser; return false; } { return result; }'
].join("\n"), options);
expect(parser).toParse("a", parser);
});
it("can use options passed to the parser", function() {
var parser = PEG.buildParser([
'{ var result; }',

Loading…
Cancel
Save