diff --git a/README.md b/README.md index faee1b1..61f3aa1 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/lib/compiler/passes/generate-javascript.js b/lib/compiler/passes/generate-javascript.js index 16087e6..3e68abc 100644 --- a/lib/compiler/passes/generate-javascript.js +++ b/lib/compiler/passes/generate-javascript.js @@ -692,6 +692,7 @@ module.exports = function(ast, options) { '', ' function peg$parse(input) {', ' var options = arguments.length > 1 ? arguments[1] : {},', + ' parser = this,', '', ' peg$FAILED = {},', '' diff --git a/lib/parser.js b/lib/parser.js index d7d8b88..de84adf 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -26,6 +26,7 @@ module.exports = (function() { function peg$parse(input) { var options = arguments.length > 1 ? arguments[1] : {}, + parser = this, peg$FAILED = {}, diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index daa7f35..4ec57f8 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -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; }',