Make the generated parsers standalone (no runtime is required).
This and also speeds up the benchmark suite execution by 7.83 % on V8. Detailed results (benchmark suite totals): --------------------------------- Test # Before After --------------------------------- 1 26.17 kB/s 28.16 kB/s 2 26.05 kB/s 28.16 kB/s 3 25.99 kB/s 28.10 kB/s 4 26.13 kB/s 28.11 kB/s 5 26.14 kB/s 28.07 kB/s --------------------------------- Average 26.10 kB/s 28.14 kB/s --------------------------------- Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2redux
parent
3f85a9ca84
commit
e63f64a3d5
File diff suppressed because it is too large
Load Diff
@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* PEG.js runtime.
|
|
||||||
*
|
|
||||||
* Required by all parsers generated by PEG.js.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PEG = {};
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
/* ===== PEG.ArrayUtils ===== */
|
|
||||||
|
|
||||||
/* Array manipulation utility functions. */
|
|
||||||
|
|
||||||
PEG.ArrayUtils = {
|
|
||||||
each: function(array, callback) {
|
|
||||||
var length = array.length;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
callback(array[i]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
map: function(array, callback) {
|
|
||||||
var result = [];
|
|
||||||
var length = array.length;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
result[i] = callback(array[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ===== PEG.StringUtils ===== */
|
|
||||||
|
|
||||||
/* String manipulation utility functions. */
|
|
||||||
|
|
||||||
PEG.StringUtils = {
|
|
||||||
/*
|
|
||||||
* Surrounds the string with quotes and escapes characters inside so that the
|
|
||||||
* result is a valid JavaScript string.
|
|
||||||
*/
|
|
||||||
quote: function(s) {
|
|
||||||
/*
|
|
||||||
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
|
|
||||||
* literal except for the closing quote character, backslash, carriage
|
|
||||||
* return, line separator, paragraph separator, and line feed. Any character
|
|
||||||
* may appear in the form of an escape sequence.
|
|
||||||
*/
|
|
||||||
return '"' + s
|
|
||||||
.replace(/\\/g, '\\\\') // backslash
|
|
||||||
.replace(/"/g, '\\"') // closing quote character
|
|
||||||
.replace(/\r/g, '\\r') // carriage return
|
|
||||||
.replace(/\u2028/g, '\\u2028') // line separator
|
|
||||||
.replace(/\u2029/g, '\\u2029') // paragraph separator
|
|
||||||
.replace(/\n/g, '\\n') // line feed
|
|
||||||
+ '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ===== PEG.RegExpUtils ===== */
|
|
||||||
|
|
||||||
/* RegExp manipulation utility functions. */
|
|
||||||
|
|
||||||
PEG.RegExpUtils = {
|
|
||||||
/*
|
|
||||||
* Escapes characters inside the string so that it can be used as a list of
|
|
||||||
* characters in a character class of a regular expresion.
|
|
||||||
*/
|
|
||||||
quoteForClass: function(s) {
|
|
||||||
/* Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1. */
|
|
||||||
return s
|
|
||||||
.replace(/\\/g, '\\\\') // backslash
|
|
||||||
.replace(/\//g, '\\/') // closing slash
|
|
||||||
.replace(/]/g, '\\]') // closing bracket
|
|
||||||
.replace(/-/g, '\\-') // dash
|
|
||||||
.replace(/\r/g, '\\r') // carriage return
|
|
||||||
.replace(/\u2028/g, '\\u2028') // line separator
|
|
||||||
.replace(/\u2029/g, '\\u2029') // paragraph separator
|
|
||||||
.replace(/\n/g, '\\n') // line feed
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ===== PEG.Parser ===== */
|
|
||||||
|
|
||||||
/* Prototype of all parsers generated by PEG.js. */
|
|
||||||
|
|
||||||
PEG.Parser = function(startRule) { this._startRule = startRule; }
|
|
||||||
|
|
||||||
PEG.Parser.prototype = {
|
|
||||||
_matchFailed: function(failure) {
|
|
||||||
if (this._pos > this._rightmostMatchFailuresPos) {
|
|
||||||
this._rightmostMatchFailuresPos = this._pos;
|
|
||||||
this._rightmostMatchFailuresExpected = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._rightmostMatchFailuresExpected.indexOf(failure) === -1) {
|
|
||||||
this._rightmostMatchFailuresExpected.push(failure);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parses the input with a generated parser. If the parsing is successfull,
|
|
||||||
* returns a value explicitly or implicitly specified by the grammar from
|
|
||||||
* which the parser was generated (see |PEG.buildParser|). If the parsing is
|
|
||||||
* unsuccessful, throws |PEG.Parser.SyntaxError| describing the error.
|
|
||||||
*/
|
|
||||||
parse: function(input) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
function initialize() {
|
|
||||||
that._input = input;
|
|
||||||
that._pos = 0;
|
|
||||||
that._rightmostMatchFailuresPos = 0;
|
|
||||||
that._rightmostMatchFailuresExpected = [];
|
|
||||||
that._cache = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildErrorMessage() {
|
|
||||||
function buildExpected(failuresExpected) {
|
|
||||||
switch (failuresExpected.length) {
|
|
||||||
case 0:
|
|
||||||
return "end of input";
|
|
||||||
case 1:
|
|
||||||
return failuresExpected[0];
|
|
||||||
default:
|
|
||||||
failuresExpected.sort();
|
|
||||||
return failuresExpected.slice(0, failuresExpected.length - 1).join(", ")
|
|
||||||
+ " or "
|
|
||||||
+ failuresExpected[failuresExpected.length - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var expected = buildExpected(that._rightmostMatchFailuresExpected);
|
|
||||||
var pos = Math.max(that._pos, that._rightmostMatchFailuresPos);
|
|
||||||
var actual = pos < that._input.length
|
|
||||||
? PEG.StringUtils.quote(that._input.charAt(pos))
|
|
||||||
: "end of input";
|
|
||||||
|
|
||||||
return "Expected " + expected + " but " + actual + " found.";
|
|
||||||
}
|
|
||||||
|
|
||||||
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 input = that._input;
|
|
||||||
var pos = that._rightmostMatchFailuresPos;
|
|
||||||
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 };
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
var initialContext = {
|
|
||||||
reportMatchFailures: true
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = this["_parse_" + this._startRule](initialContext);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The parser is now in one of the following three states:
|
|
||||||
*
|
|
||||||
* 1. The parser successfully parsed the whole input.
|
|
||||||
*
|
|
||||||
* - |result !== null|
|
|
||||||
* - |that._pos === input.length|
|
|
||||||
* - |that._rightmostMatchFailuresExpected.length| may or may not contain
|
|
||||||
* something
|
|
||||||
*
|
|
||||||
* 2. The parser successfully parsed only a part of the input.
|
|
||||||
*
|
|
||||||
* - |result !== null|
|
|
||||||
* - |that._pos < input.length|
|
|
||||||
* - |that._rightmostMatchFailuresExpected.length| may or may not contain
|
|
||||||
* something
|
|
||||||
*
|
|
||||||
* 3. The parser did not successfully parse any part of the input.
|
|
||||||
*
|
|
||||||
* - |result === null|
|
|
||||||
* - |that._pos === 0|
|
|
||||||
* - |that._rightmostMatchFailuresExpected.length| contains at least one failure
|
|
||||||
*
|
|
||||||
* All code following this comment (including called functions) must
|
|
||||||
* handle these states.
|
|
||||||
*/
|
|
||||||
if (result === null || this._pos !== input.length) {
|
|
||||||
var errorPosition = computeErrorPosition();
|
|
||||||
throw new PEG.Parser.SyntaxError(
|
|
||||||
buildErrorMessage(),
|
|
||||||
errorPosition.line,
|
|
||||||
errorPosition.column
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Returns the parser source code. */
|
|
||||||
toSource: function() { return this._source; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ===== PEG.Parser.SyntaxError ===== */
|
|
||||||
|
|
||||||
/* Thrown when a parser encounters a syntax error. */
|
|
||||||
|
|
||||||
PEG.Parser.SyntaxError = function(message, line, column) {
|
|
||||||
this.name = "PEG.Parser.SyntaxError";
|
|
||||||
this.message = message;
|
|
||||||
this.line = line;
|
|
||||||
this.column = column;
|
|
||||||
};
|
|
||||||
|
|
||||||
PEG.Parser.SyntaxError.prototype = Error.prototype;
|
|
||||||
|
|
||||||
})();
|
|
@ -1,53 +0,0 @@
|
|||||||
(function() {
|
|
||||||
|
|
||||||
/* ===== PEG.ArrayUtils ===== */
|
|
||||||
|
|
||||||
module("PEG.ArrayUtils");
|
|
||||||
|
|
||||||
test("each", function() {
|
|
||||||
var sum;
|
|
||||||
function increment(x) { sum += x; }
|
|
||||||
|
|
||||||
sum = 0;
|
|
||||||
PEG.ArrayUtils.each([], increment);
|
|
||||||
strictEqual(sum, 0);
|
|
||||||
|
|
||||||
sum = 0;
|
|
||||||
PEG.ArrayUtils.each([1, 2, 3], increment);
|
|
||||||
strictEqual(sum, 6);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("map", function() {
|
|
||||||
function square(x) { return x * x; }
|
|
||||||
|
|
||||||
deepEqual(PEG.ArrayUtils.map([], square), []);
|
|
||||||
deepEqual(PEG.ArrayUtils.map([1, 2, 3], square), [1, 4, 9]);
|
|
||||||
});
|
|
||||||
|
|
||||||
/* ===== PEG.StringUtils ===== */
|
|
||||||
|
|
||||||
module("PEG.StringUtils");
|
|
||||||
|
|
||||||
test("quote", function() {
|
|
||||||
strictEqual(PEG.StringUtils.quote(""), '""');
|
|
||||||
strictEqual(PEG.StringUtils.quote("abcd"), '"abcd"');
|
|
||||||
strictEqual(
|
|
||||||
PEG.StringUtils.quote("\"\\\r\u2028\u2029\n\"\\\r\u2028\u2029\n"),
|
|
||||||
'"\\\"\\\\\\r\\u2028\\u2029\\n\\\"\\\\\\r\\u2028\\u2029\\n"'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/* ===== PEG.RegExpUtils ===== */
|
|
||||||
|
|
||||||
module("PEG.RegExpUtils");
|
|
||||||
|
|
||||||
test("quoteForClass", function() {
|
|
||||||
strictEqual(PEG.RegExpUtils.quoteForClass(""), '');
|
|
||||||
strictEqual(PEG.RegExpUtils.quoteForClass("abcd"), 'abcd');
|
|
||||||
strictEqual(
|
|
||||||
PEG.RegExpUtils.quoteForClass("\\/]-\r\u2028\u2029\n\\/]-\r\u2028\u2029\n"),
|
|
||||||
'\\\\\\/\\]\\-\\r\\u2028\\u2029\\n\\\\\\/\\]\\-\\r\\u2028\\u2029\\n'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
Loading…
Reference in New Issue