From 4e46a6e46e93dff24f18e7b81136e669e669c660 Mon Sep 17 00:00:00 2001 From: David Majda Date: Sun, 2 Dec 2012 16:47:07 +0100 Subject: [PATCH] Rebuild src/parser.js (forgotten in the previous commit) --- lib/parser.js | 81 ++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/lib/parser.js b/lib/parser.js index 1c382fa..9177884 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -61,6 +61,8 @@ module.exports = (function(){ var pos = 0; var reportedPos = 0; + var cachedReportedPos = 0; + var cachedReportedPosDetails = { line: 1, column: 1, seenCR: false }; var reportFailures = 0; var rightmostFailuresPos = 0; var rightmostFailuresExpected = []; @@ -92,16 +94,48 @@ module.exports = (function(){ return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); } + function computeReportedPosDetails() { + function advanceCachedReportedPos() { + var ch; + + for (; cachedReportedPos < reportedPos; cachedReportedPos++) { + ch = input.charAt(cachedReportedPos); + if (ch === "\n") { + if (!cachedReportedPosDetails.seenCR) { cachedReportedPosDetails.line++; } + cachedReportedPosDetails.column = 1; + cachedReportedPosDetails.seenCR = false; + } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { + cachedReportedPosDetails.line++; + cachedReportedPosDetails.column = 1; + cachedReportedPosDetails.seenCR = true; + } else { + cachedReportedPosDetails.column++; + cachedReportedPosDetails.seenCR = false; + } + } + } + + if (cachedReportedPos !== reportedPos) { + if (cachedReportedPos > reportedPos) { + cachedReportedPos = 0; + cachedReportedPosDetails = { line: 1, column: 1, seenCR: false }; + } + advanceCachedReportedPos(); + } + + return cachedReportedPosDetails; + } + function offset() { return reportedPos; } function line() { - return computePosDetails(reportedPos).line; + return computeReportedPosDetails().line; } function column() { - return computePosDetails(reportedPos).column; + return computeReportedPosDetails().column; } function matchFailed(failure) { @@ -2825,37 +2859,6 @@ module.exports = (function(){ return cleanExpected; } - 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 }; - } - var utils = require("./utils"); @@ -2887,16 +2890,16 @@ module.exports = (function(){ * handle these states. */ if (result === null || pos !== input.length) { - var offset = Math.max(pos, rightmostFailuresPos); - var found = offset < input.length ? input.charAt(offset) : null; - var errorPosition = computePosDetails(Math.max(pos, rightmostFailuresPos)); + reportedPos = Math.max(pos, rightmostFailuresPos); + var found = reportedPos < input.length ? input.charAt(reportedPos) : null; + var reportedPosDetails = computeReportedPosDetails(); throw new this.SyntaxError( cleanupExpected(rightmostFailuresExpected), found, - offset, - errorPosition.line, - errorPosition.column + reportedPos, + reportedPosDetails.line, + reportedPosDetails.column ); }