Browse Source

Don't expose the "parser" variable in parser code

The "parser" variable allowed access to the parser object. Among other
things, this made it possible to invoke the parser recursively using
"parser.parse".

One problem with the "parser" variable is that it bakes in the idea that
the parser is an *object*, not a *module*. While this is true now, it
won't necessarily be in the future, when parsers may be exported as ES6
modules. Also, people tend to use parsers as modules even today, e.g.
like this:

  var parse = require("parser").parse;
  var result = parse(...);

Such usage broke the "parser" variable (as it was implemented).

For this reasons I decided to remove the "parser" variable. If someone
needs to do tricks like recursive invocation of the parser, he/she must
pass the parser or the "parse" function itself using options.

Related to #433.
redux
David Majda 5 years ago
parent
commit
e8be76ee3a
  1. 19
      README.md
  2. 4
      lib/compiler/passes/generate-js.js
  3. 36
      spec/behavior/generated-parser-behavior.spec.js

19
README.md

@ -227,10 +227,9 @@ The first rule can be preceded by an *initializer* — a piece of JavaScript cod
in curly 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 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.
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.
```pegjs
{
@ -376,8 +375,8 @@ The `start` and `end` properties both refer to the current parse position. The
`offset` property contains an offset as a zero-based index and `line` and
`column` properties contain a line and a column as one-based indices.
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.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
Note that curly braces in the predicate code must be balanced.
@ -407,8 +406,8 @@ The `start` and `end` properties both refer to the current parse position. The
`offset` property contains an offset as a zero-based index and `line` and
`column` properties contain a line and a column as one-based indices.
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.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
Note that curly braces in the predicate code must be balanced.
@ -475,8 +474,8 @@ the `end` property refers to position after the end of the expression. The
`offset` property contains an offset as a zero-based index and `line` and
`column` properties contain a line and a column as one-based indices.
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.
The code inside the action can also access options passed to the parser using
the `options` variable.
Note that curly braces in the action code must be balanced.

4
lib/compiler/passes/generate-js.js

@ -953,9 +953,7 @@ function generateJS(ast, options) {
'function peg$parse(input, options) {',
' options = options !== void 0 ? options : {};',
'',
' var parser = this,',
'',
' peg$FAILED = {},',
' var peg$FAILED = {},',
''
].join('\n'));

36
spec/behavior/generated-parser-behavior.spec.js

@ -133,15 +133,6 @@ describe("generated parser behavior", function() {
});
describe("available variables and functions", function() {
it("|parser| contains the parser object", function() {
var parser = peg.generate([
'{ var result = parser; }',
'start = "a" { return result; }'
].join("\n"), options);
expect(parser).toParse("a", parser);
});
it("|options| contains options", function() {
var parser = peg.generate([
'{ var result = options; }',
@ -568,15 +559,6 @@ describe("generated parser behavior", function() {
});
describe("available variables & functions", function() {
it("|parser| contains the parser object", function() {
var parser = peg.generate([
'{ var result; }',
'start = &{ result = parser; return true; } { return result; }'
].join("\n"), options);
expect(parser).toParse("", parser);
});
it("|options| contains options", function() {
var parser = peg.generate([
'{ var result; }',
@ -773,15 +755,6 @@ describe("generated parser behavior", function() {
});
describe("available variables & functions", function() {
it("|parser| contains the parser object", function() {
var parser = peg.generate([
'{ var result; }',
'start = !{ result = parser; return false; } { return result; }'
].join("\n"), options);
expect(parser).toParse("", parser);
});
it("|options| contains options", function() {
var parser = peg.generate([
'{ var result; }',
@ -1151,15 +1124,6 @@ describe("generated parser behavior", function() {
});
describe("available variables & functions", function() {
it("|parser| contains the parser object", function() {
var parser = peg.generate(
'start = "a" { return parser; }',
options
);
expect(parser).toParse("a", parser);
});
it("|options| contains options", function() {
var parser = peg.generate(
'start = "a" { return options; }',

Loading…
Cancel
Save