diff --git a/README.md b/README.md
index a860d22..ca4b6e7 100644
--- a/README.md
+++ b/README.md
@@ -75,8 +75,6 @@ You can tweak the generated parser with several options:
* `--cache` — makes the parser cache results, avoiding exponential parsing
time in pathological cases but making the parser slower
- * `--track-line-and-column` — makes the parser track line and column
- (available as `line` and `column` variables in the actions and predicates)
* `--allowed-start-rules` — comma-separated list of rules the parser will be
allowed to start parsing from (default: the first rule in the grammar)
@@ -105,9 +103,6 @@ object to `PEG.buildParser`. The following options are supported:
* `cache` — if `true`, makes the parser cache results, avoiding exponential
parsing time in pathological cases but making the parser slower (default:
`false`)
- * `trackLineAndColumn` — if `true`, makes the parser track line and column
- (available as `line` and `column` variables in the actions and predicates)
- (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
@@ -289,10 +284,8 @@ the initializer at the beginning of the grammar.
The code inside the predicate can also access the current parse position 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 current line and column using the `line` and `column`
-functions. Both return one-based indexes.
+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.
@@ -313,10 +306,8 @@ the initializer at the beginning of the grammar.
The code inside the predicate can also access the current parse position 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 current line and column using the `line` and `column`
-functions. Both return one-based indexes.
+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.
@@ -352,11 +343,9 @@ 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` 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` functions.
-Both return one-based indexes.
+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.
diff --git a/benchmark/index.css b/benchmark/index.css
index 9a4b378..9156969 100644
--- a/benchmark/index.css
+++ b/benchmark/index.css
@@ -30,5 +30,5 @@ a, a:visited { color: #3d586c; }
background-color: #f0f0f0;
}
#options #run-count { width: 3em; }
-#options #cache, #options #track-line-and-column { margin-left: 2em; }
+#options #cache { margin-left: 2em; }
#options #run { width: 5em; margin-left: 2em; }
diff --git a/benchmark/index.html b/benchmark/index.html
index a8633cc..5c81418 100644
--- a/benchmark/index.html
+++ b/benchmark/index.html
@@ -13,8 +13,6 @@
times
-
-
diff --git a/benchmark/index.js b/benchmark/index.js
index a31db56..874f196 100644
--- a/benchmark/index.js
+++ b/benchmark/index.js
@@ -63,8 +63,7 @@ $("#run").click(function() {
}
var options = {
- cache: $("#cache").is(":checked"),
- trackLineAndColumn: $("#track-line-and-column").is(":checked")
+ cache: $("#cache").is(":checked"),
};
Runner.run(benchmarks, runCount, options, {
@@ -106,7 +105,7 @@ $("#run").click(function() {
},
start: function() {
- $("#run-count, #cache, #track-line-and-column, #run").attr("disabled", "disabled");
+ $("#run-count, #cache, #run").attr("disabled", "disabled");
resultsTable.show();
$("#results-table tr").slice(1).remove();
@@ -123,7 +122,7 @@ $("#run").click(function() {
$.scrollTo("max", { axis: "y", duration: 500 });
- $("#run-count, #cache, #track-line-and-column, #run").removeAttr("disabled");
+ $("#run-count, #cache, #run").removeAttr("disabled");
}
});
diff --git a/benchmark/run b/benchmark/run
index 48e9c93..1882fb1 100755
--- a/benchmark/run
+++ b/benchmark/run
@@ -81,7 +81,6 @@ function printHelp() {
util.puts("Options:");
util.puts(" -n, --run-count number of runs (default: 10)");
util.puts(" --cache make tested parsers cache results");
- util.puts(" --track-line-and-column make tested parsers track line and column");
}
function exitSuccess() {
@@ -112,7 +111,7 @@ function nextArg() {
/* Main */
var runCount = 10;
-var options = { trackLineAndColumn: false };
+var options = { };
while (args.length > 0 && isOption(args[0])) {
switch (args[0]) {
@@ -132,10 +131,6 @@ while (args.length > 0 && isOption(args[0])) {
options.cache = true;
break;
- case "--track-line-and-column":
- options.trackLineAndColumn = true;
- break;
-
case "-h":
case "--help":
printHelp();
diff --git a/bin/pegjs b/bin/pegjs
index 4fe30ab..3c1421e 100755
--- a/bin/pegjs
+++ b/bin/pegjs
@@ -25,7 +25,6 @@ function printHelp() {
util.puts(" object will be stored (default:");
util.puts(" \"module.exports\")");
util.puts(" --cache make generated parser cache results");
- util.puts(" --track-line-and-column make generated parser track line and column");
util.puts(" --allowed-start-rules comma-separated list of rules the generated");
util.puts(" parser will be allowed to start parsing");
util.puts(" from (default: the first rule in the");
@@ -73,7 +72,6 @@ function readStream(inputStream, callback) {
var exportVar = "module.exports";
var options = {
cache: false,
- trackLineAndColumn: false,
output: "source"
};
@@ -92,10 +90,6 @@ while (args.length > 0 && isOption(args[0])) {
options.cache = true;
break;
- case "--track-line-and-column":
- options.trackLineAndColumn = true;
- break;
-
case "--allowed-start-rules":
nextArg();
if (args.length === 0) {
diff --git a/lib/compiler/passes/generate-code.js b/lib/compiler/passes/generate-code.js
index 8bf93de..3faf8f2 100644
--- a/lib/compiler/passes/generate-code.js
+++ b/lib/compiler/passes/generate-code.js
@@ -5,7 +5,6 @@ module.exports = function(ast, options) {
options = utils.clone(options);
utils.defaults(options, {
cache: false,
- trackLineAndColumn: false,
allowedStartRules: [ast.startRule]
});
@@ -333,10 +332,10 @@ module.exports = function(ast, options) {
' startRule = #{string(options.allowedStartRules[0])};',
' }',
' ',
- ' #{posInit("pos")};',
- ' #{posInit("reportedPos")};',
+ ' var pos = 0;',
+ ' var reportedPos = 0;',
' var reportFailures = 0;', // 0 = report, anything > 0 = do not report
- ' #{posInit("rightmostFailuresPos")};',
+ ' var rightmostFailuresPos = 0;',
' var rightmostFailuresExpected = [];',
' #if options.cache',
' var cache = {};',
@@ -372,56 +371,24 @@ module.exports = function(ast, options) {
' }',
' ',
' function offset() {',
- ' return #{posOffset("reportedPos")};',
+ ' return reportedPos;',
+ ' }',
+ ' ',
+ ' function line() {',
+ ' return computePosDetails(reportedPos).line;',
+ ' }',
+ ' ',
+ ' function column() {',
+ ' return computePosDetails(reportedPos).column;',
' }',
' ',
- ' #if options.trackLineAndColumn',
- ' function line() {',
- ' return reportedPos.line;',
- ' }',
- ' ',
- ' function column() {',
- ' return reportedPos.column;',
- ' }',
- ' ',
- ' function clone(object) {',
- ' var result = {};',
- ' for (var key in object) {',
- ' result[key] = object[key];',
- ' }',
- ' return result;',
- ' }',
- ' ',
- ' function advance(pos, n) {',
- ' var endOffset = pos.offset + n;',
- ' ',
- ' for (var offset = pos.offset; offset < endOffset; offset++) {',
- ' var ch = input.charAt(offset);',
- ' if (ch === "\\n") {',
- ' if (!pos.seenCR) { pos.line++; }',
- ' pos.column = 1;',
- ' pos.seenCR = false;',
- ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
- ' pos.line++;',
- ' pos.column = 1;',
- ' pos.seenCR = true;',
- ' } else {',
- ' pos.column++;',
- ' pos.seenCR = false;',
- ' }',
- ' }',
- ' ',
- ' pos.offset += n;',
- ' }',
- ' ',
- ' #end',
' function matchFailed(failure) {',
- ' if (#{posOffset("pos")} < #{posOffset("rightmostFailuresPos")}) {',
+ ' if (pos < rightmostFailuresPos) {',
' return;',
' }',
' ',
- ' if (#{posOffset("pos")} > #{posOffset("rightmostFailuresPos")}) {',
- ' rightmostFailuresPos = #{posClone("pos")};',
+ ' if (pos > rightmostFailuresPos) {',
+ ' rightmostFailuresPos = pos;',
' rightmostFailuresExpected = [];',
' }',
' ',
@@ -447,38 +414,36 @@ module.exports = function(ast, options) {
' return cleanExpected;',
' }',
' ',
- ' #if !options.trackLineAndColumn',
- ' function computeErrorPosition() {',
- ' /*',
- ' * The first idea was to use |String.split| to break the input up to the',
- ' * error position along newlines and derive the line and column from',
- ' * there. However IE\'s |split| implementation is so broken that it was',
- ' * enough to prevent it.',
- ' */',
- ' ',
- ' var line = 1;',
- ' var column = 1;',
- ' var seenCR = false;',
- ' ',
- ' for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {',
- ' var ch = input.charAt(i);',
- ' if (ch === "\\n") {',
- ' if (!seenCR) { line++; }',
- ' column = 1;',
- ' seenCR = false;',
- ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
- ' line++;',
- ' column = 1;',
- ' seenCR = true;',
- ' } else {',
- ' column++;',
- ' seenCR = false;',
- ' }',
+ ' function computePosDetails(pos) {',
+ ' /*',
+ ' * The first idea was to use |String.split| to break the input up to the',
+ ' * error position along newlines and derive the line and column from',
+ ' * there. However IE\'s |split| implementation is so broken that it was',
+ ' * enough to prevent it.',
+ ' */',
+ ' ',
+ ' var line = 1;',
+ ' var column = 1;',
+ ' var seenCR = false;',
+ ' ',
+ ' for (var i = 0; i < pos; i++) {',
+ ' var ch = input.charAt(i);',
+ ' if (ch === "\\n") {',
+ ' if (!seenCR) { line++; }',
+ ' column = 1;',
+ ' seenCR = false;',
+ ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
+ ' line++;',
+ ' column = 1;',
+ ' seenCR = true;',
+ ' } else {',
+ ' column++;',
+ ' seenCR = false;',
' }',
- ' ',
- ' return { line: line, column: column };',
' }',
- ' #end',
+ ' ',
+ ' return { line: line, column: column };',
+ ' }',
' ',
' #if node.initializer',
' #block emit(node.initializer)',
@@ -492,32 +457,28 @@ module.exports = function(ast, options) {
' * 1. The parser successfully parsed the whole input.',
' *',
' * - |result !== null|',
- ' * - |#{posOffset("pos")} === input.length|',
+ ' * - |pos === input.length|',
' * - |rightmostFailuresExpected| may or may not contain something',
' *',
' * 2. The parser successfully parsed only a part of the input.',
' *',
' * - |result !== null|',
- ' * - |#{posOffset("pos")} < input.length|',
+ ' * - |pos < input.length|',
' * - |rightmostFailuresExpected| may or may not contain something',
' *',
' * 3. The parser did not successfully parse any part of the input.',
' *',
' * - |result === null|',
- ' * - |#{posOffset("pos")} === 0|',
+ ' * - |pos === 0|',
' * - |rightmostFailuresExpected| contains at least one failure',
' *',
' * All code following this comment (including called functions) must',
' * handle these states.',
' */',
- ' if (result === null || #{posOffset("pos")} !== input.length) {',
- ' var offset = Math.max(#{posOffset("pos")}, #{posOffset("rightmostFailuresPos")});',
+ ' if (result === null || pos !== input.length) {',
+ ' var offset = Math.max(pos, rightmostFailuresPos);',
' var found = offset < input.length ? input.charAt(offset) : null;',
- ' #if options.trackLineAndColumn',
- ' var errorPosition = #{posOffset("pos")} > #{posOffset("rightmostFailuresPos")} ? pos : rightmostFailuresPos;',
- ' #else',
- ' var errorPosition = computeErrorPosition();',
- ' #end',
+ ' var errorPosition = computePosDetails(Math.max(pos, rightmostFailuresPos));',
' ',
' throw new this.SyntaxError(',
' cleanupExpected(rightmostFailuresExpected),',
@@ -573,10 +534,10 @@ module.exports = function(ast, options) {
rule: [
'function parse_#{node.name}() {',
' #if options.cache',
- ' var cacheKey = "#{node.name}@" + #{posOffset("pos")};',
+ ' var cacheKey = "#{node.name}@" + pos;',
' var cachedResult = cache[cacheKey];',
' if (cachedResult) {',
- ' pos = #{posClone("cachedResult.nextPos")};',
+ ' pos = cachedResult.nextPos;',
' return cachedResult.result;',
' }',
' ',
@@ -589,7 +550,7 @@ module.exports = function(ast, options) {
' #if options.cache',
' ',
' cache[cacheKey] = {',
- ' nextPos: #{posClone("pos")},',
+ ' nextPos: pos,',
' result: #{r(node.expression.resultIndex)}',
' };',
' #end',
@@ -614,18 +575,18 @@ module.exports = function(ast, options) {
'}'
],
action: [
- '#{posSave(node)};',
+ '#{r(node.posIndex)} = pos;',
'#block emit(node.expression)',
'if (#{r(node.resultIndex)} !== null) {',
- ' reportedPos = #{posClone(r(node.posIndex))};',
+ ' reportedPos = #{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)};',
+ ' pos = #{r(node.posIndex)};',
'}'
],
sequence: [
- '#{posSave(node)};',
+ '#{r(node.posIndex)} = pos;',
'#block code'
],
"sequence.iteration": [
@@ -634,26 +595,26 @@ module.exports = function(ast, options) {
' #block code',
'} else {',
' #{r(node.resultIndex)} = null;',
- ' #{posRestore(node)};',
+ ' pos = #{r(node.posIndex)};',
'}'
],
"sequence.inner": [
'#{r(node.resultIndex)} = [#{map(pluck(node.elements, "resultIndex"), r).join(", ")}];'
],
simple_and: [
- '#{posSave(node)};',
+ '#{r(node.posIndex)} = pos;',
'reportFailures++;',
'#block emit(node.expression)',
'reportFailures--;',
'if (#{r(node.resultIndex)} !== null) {',
' #{r(node.resultIndex)} = "";',
- ' #{posRestore(node)};',
+ ' pos = #{r(node.posIndex)};',
'} else {',
' #{r(node.resultIndex)} = null;',
'}'
],
simple_not: [
- '#{posSave(node)};',
+ '#{r(node.posIndex)} = pos;',
'reportFailures++;',
'#block emit(node.expression)',
'reportFailures--;',
@@ -661,15 +622,15 @@ module.exports = function(ast, options) {
' #{r(node.resultIndex)} = "";',
'} else {',
' #{r(node.resultIndex)} = null;',
- ' #{posRestore(node)};',
+ ' pos = #{r(node.posIndex)};',
'}'
],
semantic_and: [
- 'reportedPos = #{posClone("pos")};',
+ 'reportedPos = pos;',
'#{r(node.resultIndex)} = (function(#{keys(node.params).join(", ")}) {#{node.code}})(#{map(values(node.params), r).join(", ")}) ? "" : null;'
],
semantic_not: [
- 'reportedPos = #{posClone("pos")};',
+ 'reportedPos = pos;',
'#{r(node.resultIndex)} = (function(#{keys(node.params).join(", ")}) {#{node.code}})(#{map(values(node.params), r).join(", ")}) ? null : "";'
],
optional: [
@@ -705,9 +666,9 @@ module.exports = function(ast, options) {
'#else',
' #if !node.ignoreCase',
' #if node.value.length === 1',
- ' if (input.charCodeAt(#{posOffset("pos")}) === #{node.value.charCodeAt(0)}) {',
+ ' if (input.charCodeAt(pos) === #{node.value.charCodeAt(0)}) {',
' #else',
- ' if (input.substr(#{posOffset("pos")}, #{node.value.length}) === #{string(node.value)}) {',
+ ' if (input.substr(pos, #{node.value.length}) === #{string(node.value)}) {',
' #end',
' #else',
/*
@@ -718,14 +679,14 @@ module.exports = function(ast, options) {
* meaning the result of lowercasing a character can be more
* characters.
*/
- ' if (input.substr(#{posOffset("pos")}, #{node.value.length}).toLowerCase() === #{string(node.value.toLowerCase())}) {',
+ ' if (input.substr(pos, #{node.value.length}).toLowerCase() === #{string(node.value.toLowerCase())}) {',
' #end',
' #if !node.ignoreCase',
' #{r(node.resultIndex)} = #{string(node.value)};',
' #else',
- ' #{r(node.resultIndex)} = input.substr(#{posOffset("pos")}, #{node.value.length});',
+ ' #{r(node.resultIndex)} = input.substr(pos, #{node.value.length});',
' #end',
- ' #{posAdvance(node.value.length)};',
+ ' #{node.value.length > 1 ? "pos += " + node.value.length : "pos++"};',
' } else {',
' #{r(node.resultIndex)} = null;',
' if (reportFailures === 0) {',
@@ -735,9 +696,9 @@ module.exports = function(ast, options) {
'#end'
],
"class": [
- 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {',
- ' #{r(node.resultIndex)} = input.charAt(#{posOffset("pos")});',
- ' #{posAdvance(1)};',
+ 'if (#{regexp}.test(input.charAt(pos))) {',
+ ' #{r(node.resultIndex)} = input.charAt(pos);',
+ ' pos++;',
'} else {',
' #{r(node.resultIndex)} = null;',
' if (reportFailures === 0) {',
@@ -746,9 +707,9 @@ module.exports = function(ast, options) {
'}'
],
any: [
- 'if (input.length > #{posOffset("pos")}) {',
- ' #{r(node.resultIndex)} = input.charAt(#{posOffset("pos")});',
- ' #{posAdvance(1)};',
+ 'if (input.length > pos) {',
+ ' #{r(node.resultIndex)} = input.charAt(pos);',
+ ' pos++;',
'} else {',
' #{r(node.resultIndex)} = null;',
' if (reportFailures === 0) {',
@@ -777,34 +738,6 @@ module.exports = function(ast, options) {
vars.r = function(index) { return "r" + index; };
- /* Position-handling macros */
- if (options.trackLineAndColumn) {
- vars.posInit = function(name) {
- return "var "
- + name
- + " = "
- + "{ offset: 0, line: 1, column: 1, seenCR: false }";
- };
- vars.posClone = function(name) { return "clone(" + name + ")"; };
- vars.posOffset = function(name) { return name + ".offset"; };
-
- vars.posAdvance = function(n) { return "advance(pos, " + n + ")"; };
- } else {
- vars.posInit = function(name) { return "var " + name + " = 0"; };
- vars.posClone = function(name) { return name; };
- vars.posOffset = function(name) { return name; };
-
- vars.posAdvance = function(n) {
- return n === 1 ? "pos++" : "pos += " + n;
- };
- }
- vars.posSave = function(node) {
- return vars.r(node.posIndex) + " = " + vars.posClone("pos");
- };
- vars.posRestore = function(node) {
- return "pos" + " = " + vars.posClone(vars.r(node.posIndex));
- };
-
return templates[name](vars);
}
diff --git a/lib/parser.js b/lib/parser.js
index 5cab64a..1c382fa 100644
--- a/lib/parser.js
+++ b/lib/parser.js
@@ -96,6 +96,14 @@ module.exports = (function(){
return reportedPos;
}
+ function line() {
+ return computePosDetails(reportedPos).line;
+ }
+
+ function column() {
+ return computePosDetails(reportedPos).column;
+ }
+
function matchFailed(failure) {
if (pos < rightmostFailuresPos) {
return;
@@ -2817,7 +2825,7 @@ module.exports = (function(){
return cleanExpected;
}
- function computeErrorPosition() {
+ function computePosDetails(pos) {
/*
* The first idea was to use |String.split| to break the input up to the
* error position along newlines and derive the line and column from
@@ -2829,7 +2837,7 @@ module.exports = (function(){
var column = 1;
var seenCR = false;
- for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
+ for (var i = 0; i < pos; i++) {
var ch = input.charAt(i);
if (ch === "\n") {
if (!seenCR) { line++; }
@@ -2881,7 +2889,7 @@ module.exports = (function(){
if (result === null || pos !== input.length) {
var offset = Math.max(pos, rightmostFailuresPos);
var found = offset < input.length ? input.charAt(offset) : null;
- var errorPosition = computeErrorPosition();
+ var errorPosition = computePosDetails(Math.max(pos, rightmostFailuresPos));
throw new this.SyntaxError(
cleanupExpected(rightmostFailuresExpected),
diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js
index 1c8092c..09be92e 100644
--- a/spec/generated-parser.spec.js
+++ b/spec/generated-parser.spec.js
@@ -1,9 +1,6 @@
describe("generated parser", function() {
function vary(names, block) {
- var values = {
- trackLineAndColumn: [false, true],
- cache: [false, true]
- };
+ var values = { cache: [false, true] };
function varyStep(names, options) {
var clonedOptions = {}, key, name, i;
@@ -35,7 +32,7 @@ describe("generated parser", function() {
}
function varyAll(block) {
- vary(["cache", "trackLineAndColumn"], block);
+ vary(["cache"], block);
}
beforeEach(function() {
@@ -267,30 +264,28 @@ describe("generated parser", function() {
expect(parser).toParse("ab", ["a", 1]);
});
- if (options.trackLineAndColumn) {
- 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()]; }',
- 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
- ].join("\n"), options);
+ 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()]; }',
+ 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
+ ].join("\n"), options);
- expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
+ expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
- /* Non-Unix newlines */
- expect(parser).toParse("1\rx", [2, 1]); // Old Mac
- expect(parser).toParse("1\r\nx", [2, 1]); // Windows
- expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
+ /* Non-Unix newlines */
+ expect(parser).toParse("1\rx", [2, 1]); // Old Mac
+ expect(parser).toParse("1\r\nx", [2, 1]); // Windows
+ expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
- /* Strange newlines */
- expect(parser).toParse("1\u2028x", [2, 1]); // line separator
- expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
- });
- }
+ /* Strange newlines */
+ expect(parser).toParse("1\u2028x", [2, 1]); // line separator
+ expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
+ });
it("can use variables defined in the initializer", function() {
var parser = PEG.buildParser([
@@ -431,30 +426,28 @@ describe("generated parser", function() {
expect(parser).toParse("a", ["a", ""]);
});
- if (options.trackLineAndColumn) {
- 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"',
- 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
- ].join("\n"), options);
+ 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"',
+ 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
+ ].join("\n"), options);
- expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
+ expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
- /* Non-Unix newlines */
- expect(parser).toParse("1\rx", [2, 1]); // Old Mac
- expect(parser).toParse("1\r\nx", [2, 1]); // Windows
- expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
+ /* Non-Unix newlines */
+ expect(parser).toParse("1\rx", [2, 1]); // Old Mac
+ expect(parser).toParse("1\r\nx", [2, 1]); // Windows
+ expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
- /* Strange newlines */
- expect(parser).toParse("1\u2028x", [2, 1]); // line separator
- expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
- });
- }
+ /* Strange newlines */
+ expect(parser).toParse("1\u2028x", [2, 1]); // line separator
+ expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
+ });
it("can use variables defined in the initializer", function() {
var parser = PEG.buildParser([
@@ -515,30 +508,28 @@ describe("generated parser", function() {
expect(parser).toParse("a", ["a", ""]);
});
- if (options.trackLineAndColumn) {
- 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"',
- 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
- ].join("\n"), options);
+ 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"',
+ 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
+ ].join("\n"), options);
- expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
+ expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
- /* Non-Unix newlines */
- expect(parser).toParse("1\rx", [2, 1]); // Old Mac
- expect(parser).toParse("1\r\nx", [2, 1]); // Windows
- expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
+ /* Non-Unix newlines */
+ expect(parser).toParse("1\rx", [2, 1]); // Old Mac
+ expect(parser).toParse("1\r\nx", [2, 1]); // Windows
+ expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
- /* Strange newlines */
- expect(parser).toParse("1\u2028x", [2, 1]); // line separator
- expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
- });
- }
+ /* Strange newlines */
+ expect(parser).toParse("1\u2028x", [2, 1]); // line separator
+ expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
+ });
it("can use variables defined in the initializer", function() {
var parser = PEG.buildParser([