Position tracking: Make |offset|, |line| and |column| functions

This will allow to compute position data lazily and get rid of the
|trackLineAndColumn| option without affecting performance of generated
parsers that don't use position data.
redux
David Majda 12 years ago
parent da9ab1bf17
commit da8c455640

@ -288,11 +288,11 @@ The code inside the predicate can access all variables and functions defined in
the initializer at the beginning of the grammar.
The code inside the predicate can also access the current parse position using
the `offset` variable. It is a zero-based character index into the input string.
If the `trackLineAndColumn` option was set to `true` when the parser was
the `offset` function. It returns a zero-based character index into the input
string. If the `trackLineAndColumn` option was set to `true` when the parser was
generated (or `--track-line-and-column` was used on the command line), the code
can also access the current line and column using the `line` and `column`
variables. Both are one-based indexes.
functions. Both return one-based indexes.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
@ -312,11 +312,11 @@ The code inside the predicate can access all variables and functions defined in
the initializer at the beginning of the grammar.
The code inside the predicate can also access the current parse position using
the `offset` variable. It is a zero-based character index into the input string.
If the `trackLineAndColumn` option was set to `true` when the parser was
the `offset` function. It returns a zero-based character index into the input
string. If the `trackLineAndColumn` option was set to `true` when the parser was
generated (or `--track-line-and-column` was used on the command line), the code
can also access the current line and column using the `line` and `column`
variables. Both are one-based indexes.
functions. Both return one-based indexes.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
@ -351,12 +351,12 @@ initializer at the beginning of the grammar. Curly braces in the action code
must be balanced.
The code inside the action can also access the parse position at the beginning
of the action's expression using the `offset` variable. It is a zero-based
of the action's expression using the `offset` function. It returns a zero-based
character index into the input string. If the `trackLineAndColumn` option was
set to `true` when the parser was generated (or `--track-line-and-column` was
used on the command line), the code can also access the line and column at the
beginning of the action's expression using the `line` and `column` variables.
Both are one-based indexes.
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.

@ -334,6 +334,7 @@ module.exports = function(ast, options) {
' }',
' ',
' #{posInit("pos")};',
' #{posInit("reportedPos")};',
' var reportFailures = 0;', // 0 = report, anything > 0 = do not report
' #{posInit("rightmostFailuresPos")};',
' var rightmostFailuresExpected = [];',
@ -370,7 +371,19 @@ module.exports = function(ast, options) {
' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);',
' }',
' ',
' function offset() {',
' return #{posOffset("reportedPos")};',
' }',
' ',
' #if options.trackLineAndColumn',
' function line() {',
' return reportedPos.line;',
' }',
' ',
' function column() {',
' return reportedPos.column;',
' }',
' ',
' function clone(object) {',
' var result = {};',
' for (var key in object) {',
@ -604,7 +617,8 @@ module.exports = function(ast, options) {
'#{posSave(node)};',
'#block emit(node.expression)',
'if (#{r(node.resultIndex)} !== null) {',
' #{r(node.resultIndex)} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? [r(node.posIndex) + ".offset", r(node.posIndex) + ".line", r(node.posIndex) + ".column"] : [r(node.posIndex)]).concat(map(values(node.params), r)).join(", ")});',
' reportedPos = #{posClone(r(node.posIndex))};',
' #{r(node.resultIndex)} = (function(#{keys(node.params).join(", ")}) {#{node.code}})(#{map(values(node.params), r).join(", ")});',
'}',
'if (#{r(node.resultIndex)} === null) {',
' #{posRestore(node)};',
@ -651,10 +665,12 @@ module.exports = function(ast, options) {
'}'
],
semantic_and: [
'#{r(node.resultIndex)} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(map(values(node.params), r)).join(", ")}) ? "" : null;'
'reportedPos = #{posClone("pos")};',
'#{r(node.resultIndex)} = (function(#{keys(node.params).join(", ")}) {#{node.code}})(#{map(values(node.params), r).join(", ")}) ? "" : null;'
],
semantic_not: [
'#{r(node.resultIndex)} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(map(values(node.params), r)).join(", ")}) ? null : "";'
'reportedPos = #{posClone("pos")};',
'#{r(node.resultIndex)} = (function(#{keys(node.params).join(", ")}) {#{node.code}})(#{map(values(node.params), r).join(", ")}) ? null : "";'
],
optional: [
'#block emit(node.expression)',

@ -60,6 +60,7 @@ module.exports = (function(){
}
var pos = 0;
var reportedPos = 0;
var reportFailures = 0;
var rightmostFailuresPos = 0;
var rightmostFailuresExpected = [];
@ -91,6 +92,10 @@ module.exports = (function(){
return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
}
function offset() {
return reportedPos;
}
function matchFailed(failure) {
if (pos < rightmostFailuresPos) {
return;
@ -139,14 +144,15 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, initializer, rules) {
reportedPos = r1;
r0 = (function(initializer, rules) {
return {
type: "grammar",
initializer: initializer !== "" ? initializer : null,
rules: rules,
startRule: rules[0].name
};
})(r1, r4, r5);
})(r4, r5);
}
if (r0 === null) {
pos = r1;
@ -174,12 +180,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, code) {
reportedPos = r1;
r0 = (function(code) {
return {
type: "initializer",
code: code
};
})(r1, r3);
})(r3);
}
if (r0 === null) {
pos = r1;
@ -226,7 +233,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, name, displayName, expression) {
reportedPos = r1;
r0 = (function(name, displayName, expression) {
return {
type: "rule",
name: name,
@ -238,7 +246,7 @@ module.exports = (function(){
}
: expression
};
})(r1, r3, r4, r6);
})(r3, r4, r6);
}
if (r0 === null) {
pos = r1;
@ -296,7 +304,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, head, tail) {
reportedPos = r1;
r0 = (function(head, tail) {
if (tail.length > 0) {
var alternatives = [head].concat(utils.map(
tail,
@ -309,7 +318,7 @@ module.exports = (function(){
} else {
return head;
}
})(r1, r3, r4);
})(r3, r4);
}
if (r0 === null) {
pos = r1;
@ -341,7 +350,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, elements, code) {
reportedPos = r1;
r0 = (function(elements, code) {
var expression = elements.length !== 1
? {
type: "sequence",
@ -353,7 +363,7 @@ module.exports = (function(){
expression: expression,
code: code
};
})(r1, r3, r4);
})(r3, r4);
}
if (r0 === null) {
pos = r1;
@ -367,14 +377,15 @@ module.exports = (function(){
r2 = parse_labeled();
}
if (r0 !== null) {
r0 = (function(offset, elements) {
reportedPos = r1;
r0 = (function(elements) {
return elements.length !== 1
? {
type: "sequence",
elements: elements
}
: elements[0];
})(r1, r0);
})(r0);
}
if (r0 === null) {
pos = r1;
@ -408,13 +419,14 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, label, expression) {
reportedPos = r1;
r0 = (function(label, expression) {
return {
type: "labeled",
label: label,
expression: expression
};
})(r1, r3, r5);
})(r3, r5);
}
if (r0 === null) {
pos = r1;
@ -444,12 +456,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, code) {
reportedPos = r1;
r0 = (function(code) {
return {
type: "semantic_and",
code: code
};
})(r1, r4);
})(r4);
}
if (r0 === null) {
pos = r1;
@ -471,12 +484,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, expression) {
reportedPos = r1;
r0 = (function(expression) {
return {
type: "simple_and",
expression: expression
};
})(r1, r4);
})(r4);
}
if (r0 === null) {
pos = r1;
@ -498,12 +512,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, code) {
reportedPos = r1;
r0 = (function(code) {
return {
type: "semantic_not",
code: code
};
})(r1, r4);
})(r4);
}
if (r0 === null) {
pos = r1;
@ -525,12 +540,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, expression) {
reportedPos = r1;
r0 = (function(expression) {
return {
type: "simple_not",
expression: expression
};
})(r1, r4);
})(r4);
}
if (r0 === null) {
pos = r1;
@ -563,12 +579,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, expression) {
reportedPos = r1;
r0 = (function(expression) {
return {
type: "optional",
expression: expression
};
})(r1, r3);
})(r3);
}
if (r0 === null) {
pos = r1;
@ -590,12 +607,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, expression) {
reportedPos = r1;
r0 = (function(expression) {
return {
type: "zero_or_more",
expression: expression
};
})(r1, r3);
})(r3);
}
if (r0 === null) {
pos = r1;
@ -617,12 +635,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, expression) {
reportedPos = r1;
r0 = (function(expression) {
return {
type: "one_or_more",
expression: expression
};
})(r1, r3);
})(r3);
}
if (r0 === null) {
pos = r1;
@ -677,12 +696,13 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, name) {
reportedPos = r1;
r0 = (function(name) {
return {
type: "rule_ref",
name: name
};
})(r1, r3);
})(r3);
}
if (r0 === null) {
pos = r1;
@ -695,7 +715,8 @@ module.exports = (function(){
r1 = pos;
r0 = parse_dot();
if (r0 !== null) {
r0 = (function(offset) { return { type: "any" }; })(r1);
reportedPos = r1;
r0 = (function() { return { type: "any" }; })();
}
if (r0 === null) {
pos = r1;
@ -723,7 +744,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, expression) { return expression; })(r1, r4);
reportedPos = r1;
r0 = (function(expression) { return expression; })(r4);
}
if (r0 === null) {
pos = r1;
@ -755,7 +777,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, braced) { return braced.substr(1, braced.length - 2); })(r1, r3);
reportedPos = r1;
r0 = (function(braced) { return braced.substr(1, braced.length - 2); })(r3);
}
if (r0 === null) {
pos = r1;
@ -819,9 +842,10 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, parts) {
reportedPos = r1;
r0 = (function(parts) {
return "{" + parts.join("") + "}";
})(r1, r4);
})(r4);
}
if (r0 === null) {
pos = r1;
@ -844,7 +868,8 @@ module.exports = (function(){
r0 = null;
}
if (r0 !== null) {
r0 = (function(offset, chars) { return chars.join(""); })(r1, r0);
reportedPos = r1;
r0 = (function(chars) { return chars.join(""); })(r0);
}
if (r0 === null) {
pos = r1;
@ -894,7 +919,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "="; })(r1);
reportedPos = r1;
r0 = (function() { return "="; })();
}
if (r0 === null) {
pos = r1;
@ -929,7 +955,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return ":"; })(r1);
reportedPos = r1;
r0 = (function() { return ":"; })();
}
if (r0 === null) {
pos = r1;
@ -964,7 +991,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return ";"; })(r1);
reportedPos = r1;
r0 = (function() { return ";"; })();
}
if (r0 === null) {
pos = r1;
@ -999,7 +1027,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "/"; })(r1);
reportedPos = r1;
r0 = (function() { return "/"; })();
}
if (r0 === null) {
pos = r1;
@ -1034,7 +1063,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "&"; })(r1);
reportedPos = r1;
r0 = (function() { return "&"; })();
}
if (r0 === null) {
pos = r1;
@ -1069,7 +1099,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "!"; })(r1);
reportedPos = r1;
r0 = (function() { return "!"; })();
}
if (r0 === null) {
pos = r1;
@ -1104,7 +1135,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "?"; })(r1);
reportedPos = r1;
r0 = (function() { return "?"; })();
}
if (r0 === null) {
pos = r1;
@ -1139,7 +1171,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "*"; })(r1);
reportedPos = r1;
r0 = (function() { return "*"; })();
}
if (r0 === null) {
pos = r1;
@ -1174,7 +1207,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "+"; })(r1);
reportedPos = r1;
r0 = (function() { return "+"; })();
}
if (r0 === null) {
pos = r1;
@ -1209,7 +1243,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "("; })(r1);
reportedPos = r1;
r0 = (function() { return "("; })();
}
if (r0 === null) {
pos = r1;
@ -1244,7 +1279,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return ")"; })(r1);
reportedPos = r1;
r0 = (function() { return ")"; })();
}
if (r0 === null) {
pos = r1;
@ -1279,7 +1315,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "."; })(r1);
reportedPos = r1;
r0 = (function() { return "."; })();
}
if (r0 === null) {
pos = r1;
@ -1390,9 +1427,10 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, head, tail) {
reportedPos = r1;
r0 = (function(head, tail) {
return head + tail.join("");
})(r1, r3, r4);
})(r3, r4);
}
if (r0 === null) {
pos = r1;
@ -1442,13 +1480,14 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, value, flags) {
reportedPos = r1;
r0 = (function(value, flags) {
return {
type: "literal",
value: value,
ignoreCase: flags === "i"
};
})(r1, r3, r4);
})(r3, r4);
}
if (r0 === null) {
pos = r1;
@ -1483,7 +1522,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, string) { return string; })(r1, r3);
reportedPos = r1;
r0 = (function(string) { return string; })(r3);
}
if (r0 === null) {
pos = r1;
@ -1541,7 +1581,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, chars) { return chars.join(""); })(r1, r4);
reportedPos = r1;
r0 = (function(chars) { return chars.join(""); })(r4);
}
if (r0 === null) {
pos = r1;
@ -1629,7 +1670,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, char_) { return char_; })(r1, r4);
reportedPos = r1;
r0 = (function(char_) { return char_; })(r4);
}
if (r0 === null) {
pos = r1;
@ -1683,7 +1725,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, chars) { return chars.join(""); })(r1, r4);
reportedPos = r1;
r0 = (function(chars) { return chars.join(""); })(r4);
}
if (r0 === null) {
pos = r1;
@ -1771,7 +1814,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, char_) { return char_; })(r1, r4);
reportedPos = r1;
r0 = (function(char_) { return char_; })(r4);
}
if (r0 === null) {
pos = r1;
@ -1868,7 +1912,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, inverted, parts, flags) {
reportedPos = r1;
r0 = (function(inverted, parts, flags) {
var partsConverted = utils.map(parts, function(part) { return part.data; });
var rawText = "["
+ inverted
@ -1884,7 +1929,7 @@ module.exports = (function(){
inverted: inverted === "^",
ignoreCase: flags === "i"
};
})(r1, r4, r5, r7);
})(r4, r5, r7);
}
if (r0 === null) {
pos = r1;
@ -1929,7 +1974,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, begin, end) {
reportedPos = r1;
r0 = (function(begin, end) {
if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
throw new this.SyntaxError(
"Invalid character range: " + begin.rawText + "-" + end.rawText + "."
@ -1941,7 +1987,7 @@ module.exports = (function(){
// FIXME: Get the raw text from the input directly.
rawText: begin.rawText + "-" + end.rawText
};
})(r1, r3, r5);
})(r3, r5);
}
if (r0 === null) {
pos = r1;
@ -1955,13 +2001,14 @@ module.exports = (function(){
r1 = pos;
r0 = parse_bracketDelimitedCharacter();
if (r0 !== null) {
r0 = (function(offset, char_) {
reportedPos = r1;
r0 = (function(char_) {
return {
data: char_,
// FIXME: Get the raw text from the input directly.
rawText: utils.quoteForRegexpClass(char_)
};
})(r1, r0);
})(r0);
}
if (r0 === null) {
pos = r1;
@ -2049,7 +2096,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, char_) { return char_; })(r1, r4);
reportedPos = r1;
r0 = (function(char_) { return char_; })(r4);
}
if (r0 === null) {
pos = r1;
@ -2132,7 +2180,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, char_) {
reportedPos = r1;
r0 = (function(char_) {
return char_
.replace("b", "\b")
.replace("f", "\f")
@ -2140,7 +2189,7 @@ module.exports = (function(){
.replace("r", "\r")
.replace("t", "\t")
.replace("v", "\x0B"); // IE does not recognize "\v".
})(r1, r5);
})(r5);
}
if (r0 === null) {
pos = r1;
@ -2184,7 +2233,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset) { return "\x00"; })(r1);
reportedPos = r1;
r0 = (function() { return "\x00"; })();
}
if (r0 === null) {
pos = r1;
@ -2225,9 +2275,10 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, h1, h2) {
reportedPos = r1;
r0 = (function(h1, h2) {
return String.fromCharCode(parseInt(h1 + h2, 16));
})(r1, r4, r5);
})(r4, r5);
}
if (r0 === null) {
pos = r1;
@ -2280,9 +2331,10 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, h1, h2, h3, h4) {
reportedPos = r1;
r0 = (function(h1, h2, h3, h4) {
return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16));
})(r1, r4, r5, r6, r7);
})(r4, r5, r6, r7);
}
if (r0 === null) {
pos = r1;
@ -2317,7 +2369,8 @@ module.exports = (function(){
pos = r2;
}
if (r0 !== null) {
r0 = (function(offset, eol) { return eol; })(r1, r4);
reportedPos = r1;
r0 = (function(eol) { return eol; })(r4);
}
if (r0 === null) {
pos = r1;

@ -258,9 +258,9 @@ describe("generated parser", function() {
expect(parser).toParse("a", "a");
});
it("can use the |offset| variable to get the current parse position", function() {
it("can use the |offset| function to get the current parse position", function() {
var parser = PEG.buildParser(
'start = "a" ("b" { return offset; })',
'start = "a" ("b" { return offset(); })',
options
);
@ -268,14 +268,14 @@ describe("generated parser", function() {
});
if (options.trackLineAndColumn) {
it("can use the |line| and |column| variables to get the current line and column", function() {
it("can use the |line| and |column| functions to get the current line and column", function() {
var parser = PEG.buildParser([
'{ var result; }',
'start = line (nl+ line)* { return result; }',
'line = thing (" "+ thing)*',
'thing = digit / mark',
'digit = [0-9]',
'mark = "x" { result = [line, column]; }',
'mark = "x" { result = [line(), column()]; }',
'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
].join("\n"), options);
@ -422,9 +422,9 @@ describe("generated parser", function() {
expect(parser).toParse("a", ["a", ""]);
});
it("can use the |offset| variable to get the current parse position", function() {
it("can use the |offset| function to get the current parse position", function() {
var parser = PEG.buildParser(
'start = "a" &{ return offset === 1; }',
'start = "a" &{ return offset() === 1; }',
options
);
@ -432,14 +432,14 @@ describe("generated parser", function() {
});
if (options.trackLineAndColumn) {
it("can use the |line| and |column| variables to get the current line and column", function() {
it("can use the |line| and |column| functions to get the current line and column", function() {
var parser = PEG.buildParser([
'{ var result; }',
'start = line (nl+ line)* { return result; }',
'line = thing (" "+ thing)*',
'thing = digit / mark',
'digit = [0-9]',
'mark = &{ result = [line, column]; return true; } "x"',
'mark = &{ result = [line(), column()]; return true; } "x"',
'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
].join("\n"), options);
@ -506,9 +506,9 @@ describe("generated parser", function() {
expect(parser).toParse("a", ["a", ""]);
});
it("can use the |offset| variable to get the current parse position", function() {
it("can use the |offset| function to get the current parse position", function() {
var parser = PEG.buildParser(
'start = "a" !{ return offset !== 1; }',
'start = "a" !{ return offset() !== 1; }',
options
);
@ -516,14 +516,14 @@ describe("generated parser", function() {
});
if (options.trackLineAndColumn) {
it("can use the |line| and |column| variables to get the current line and column", function() {
it("can use the |line| and |column| functions to get the current line and column", function() {
var parser = PEG.buildParser([
'{ var result; }',
'start = line (nl+ line)* { return result; }',
'line = thing (" "+ thing)*',
'thing = digit / mark',
'digit = [0-9]',
'mark = !{ result = [line, column]; return false; } "x"',
'mark = !{ result = [line(), column()]; return false; } "x"',
'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
].join("\n"), options);

Loading…
Cancel
Save