mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
ea87e7aaee
tokens, which for now is still completely built before parsing can proceed. For each top-level block, the source start/end positions are added as attributes to the top-most tokens. No tracking of wiki vs. html syntax yet.
4796 lines
136 KiB
JavaScript
4796 lines
136 KiB
JavaScript
/* PEG.js 0.6.1 (http://pegjs.majda.cz/) */
|
||
|
||
(function() {
|
||
|
||
var undefined;
|
||
|
||
var PEG = {
|
||
/* PEG.js version. */
|
||
VERSION: "0.6.1",
|
||
|
||
/*
|
||
* Generates a parser from a specified grammar and returns it.
|
||
*
|
||
* The grammar must be a string in the format described by the metagramar in
|
||
* the parser.pegjs file.
|
||
*
|
||
* Throws |PEG.parser.SyntaxError| if the grammar contains a syntax error or
|
||
* |PEG.GrammarError| if it contains a semantic error. Note that not all
|
||
* errors are detected during the generation and some may protrude to the
|
||
* generated parser and cause its malfunction.
|
||
*/
|
||
buildParser: function(grammar) {
|
||
return PEG.compiler.compile(PEG.parser.parse(grammar));
|
||
}
|
||
};
|
||
|
||
/* Thrown when the grammar contains an error. */
|
||
|
||
PEG.GrammarError = function(message) {
|
||
this.name = "PEG.GrammarError";
|
||
this.message = message;
|
||
};
|
||
|
||
PEG.GrammarError.prototype = Error.prototype;
|
||
|
||
function contains(array, value) {
|
||
/*
|
||
* Stupid IE does not have Array.prototype.indexOf, otherwise this function
|
||
* would be a one-liner.
|
||
*/
|
||
var length = array.length;
|
||
for (var i = 0; i < length; i++) {
|
||
if (array[i] === value) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function each(array, callback) {
|
||
var length = array.length;
|
||
for (var i = 0; i < length; i++) {
|
||
callback(array[i]);
|
||
}
|
||
}
|
||
|
||
function map(array, callback) {
|
||
var result = [];
|
||
var length = array.length;
|
||
for (var i = 0; i < length; i++) {
|
||
result[i] = callback(array[i]);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/*
|
||
* Returns a string padded on the left to a desired length with a character.
|
||
*
|
||
* The code needs to be in sync with th code template in the compilation
|
||
* function for "action" nodes.
|
||
*/
|
||
function padLeft(input, padding, length) {
|
||
var result = input;
|
||
|
||
var padLength = length - input.length;
|
||
for (var i = 0; i < padLength; i++) {
|
||
result = padding + result;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/*
|
||
* Returns an escape sequence for given character. Uses \x for characters <=
|
||
* 0xFF to save space, \u for the rest.
|
||
*
|
||
* The code needs to be in sync with th code template in the compilation
|
||
* function for "action" nodes.
|
||
*/
|
||
function escape(ch) {
|
||
var charCode = ch.charCodeAt(0);
|
||
|
||
if (charCode <= 0xFF) {
|
||
var escapeChar = 'x';
|
||
var length = 2;
|
||
} else {
|
||
var escapeChar = 'u';
|
||
var length = 4;
|
||
}
|
||
|
||
return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
|
||
}
|
||
|
||
/*
|
||
* Surrounds the string with quotes and escapes characters inside so that the
|
||
* result is a valid JavaScript string.
|
||
*
|
||
* The code needs to be in sync with th code template in the compilation
|
||
* function for "action" nodes.
|
||
*/
|
||
function quote(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.
|
||
*
|
||
* For portability, we also escape escape all non-ASCII characters.
|
||
*/
|
||
return '"' + s
|
||
.replace(/\\/g, '\\\\') // backslash
|
||
.replace(/"/g, '\\"') // closing quote character
|
||
.replace(/\r/g, '\\r') // carriage return
|
||
.replace(/\n/g, '\\n') // line feed
|
||
.replace(/[\x80-\uFFFF]/g, escape) // non-ASCII characters
|
||
+ '"';
|
||
};
|
||
|
||
/*
|
||
* Escapes characters inside the string so that it can be used as a list of
|
||
* characters in a character class of a regular expression.
|
||
*/
|
||
function quoteForRegexpClass(s) {
|
||
/*
|
||
* Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
|
||
*
|
||
* For portability, we also escape escape all non-ASCII characters.
|
||
*/
|
||
return s
|
||
.replace(/\\/g, '\\\\') // backslash
|
||
.replace(/\0/g, '\\0') // null, IE needs this
|
||
.replace(/\//g, '\\/') // closing slash
|
||
.replace(/]/g, '\\]') // closing bracket
|
||
.replace(/-/g, '\\-') // dash
|
||
.replace(/\r/g, '\\r') // carriage return
|
||
.replace(/\n/g, '\\n') // line feed
|
||
.replace(/[\x80-\uFFFF]/g, escape) // non-ASCII characters
|
||
}
|
||
|
||
/*
|
||
* Builds a node visitor -- a function which takes a node and any number of
|
||
* other parameters, calls an appropriate function according to the node type,
|
||
* passes it all its parameters and returns its value. The functions for various
|
||
* node types are passed in a parameter to |buildNodeVisitor| as a hash.
|
||
*/
|
||
function buildNodeVisitor(functions) {
|
||
return function(node) {
|
||
return functions[node.type].apply(null, arguments);
|
||
}
|
||
}
|
||
PEG.parser = (function(){
|
||
/* Generated by PEG.js 0.6.1 (http://pegjs.majda.cz/). */
|
||
|
||
var result = {
|
||
/*
|
||
* 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, startRule) {
|
||
var parseFunctions = {
|
||
"__": parse___,
|
||
"action": parse_action,
|
||
"and": parse_and,
|
||
"braced": parse_braced,
|
||
"bracketDelimitedCharacter": parse_bracketDelimitedCharacter,
|
||
"choice": parse_choice,
|
||
"class": parse_class,
|
||
"classCharacter": parse_classCharacter,
|
||
"classCharacterRange": parse_classCharacterRange,
|
||
"colon": parse_colon,
|
||
"comment": parse_comment,
|
||
"digit": parse_digit,
|
||
"dot": parse_dot,
|
||
"doubleQuotedCharacter": parse_doubleQuotedCharacter,
|
||
"doubleQuotedLiteral": parse_doubleQuotedLiteral,
|
||
"eol": parse_eol,
|
||
"eolChar": parse_eolChar,
|
||
"eolEscapeSequence": parse_eolEscapeSequence,
|
||
"equals": parse_equals,
|
||
"grammar": parse_grammar,
|
||
"hexDigit": parse_hexDigit,
|
||
"hexEscapeSequence": parse_hexEscapeSequence,
|
||
"identifier": parse_identifier,
|
||
"initializer": parse_initializer,
|
||
"labeled": parse_labeled,
|
||
"letter": parse_letter,
|
||
"literal": parse_literal,
|
||
"lowerCaseLetter": parse_lowerCaseLetter,
|
||
"lparen": parse_lparen,
|
||
"multiLineComment": parse_multiLineComment,
|
||
"nonBraceCharacter": parse_nonBraceCharacter,
|
||
"nonBraceCharacters": parse_nonBraceCharacters,
|
||
"not": parse_not,
|
||
"plus": parse_plus,
|
||
"prefixed": parse_prefixed,
|
||
"primary": parse_primary,
|
||
"question": parse_question,
|
||
"rparen": parse_rparen,
|
||
"rule": parse_rule,
|
||
"semicolon": parse_semicolon,
|
||
"sequence": parse_sequence,
|
||
"simpleBracketDelimitedCharacter": parse_simpleBracketDelimitedCharacter,
|
||
"simpleDoubleQuotedCharacter": parse_simpleDoubleQuotedCharacter,
|
||
"simpleEscapeSequence": parse_simpleEscapeSequence,
|
||
"simpleSingleQuotedCharacter": parse_simpleSingleQuotedCharacter,
|
||
"singleLineComment": parse_singleLineComment,
|
||
"singleQuotedCharacter": parse_singleQuotedCharacter,
|
||
"singleQuotedLiteral": parse_singleQuotedLiteral,
|
||
"slash": parse_slash,
|
||
"star": parse_star,
|
||
"suffixed": parse_suffixed,
|
||
"unicodeEscapeSequence": parse_unicodeEscapeSequence,
|
||
"upperCaseLetter": parse_upperCaseLetter,
|
||
"whitespace": parse_whitespace,
|
||
"zeroEscapeSequence": parse_zeroEscapeSequence
|
||
};
|
||
|
||
if (startRule !== undefined) {
|
||
if (parseFunctions[startRule] === undefined) {
|
||
throw new Error("Invalid rule name: " + quote(startRule) + ".");
|
||
}
|
||
} else {
|
||
startRule = "grammar";
|
||
}
|
||
|
||
var pos = 0;
|
||
var reportMatchFailures = true;
|
||
var rightmostMatchFailuresPos = 0;
|
||
var rightmostMatchFailuresExpected = [];
|
||
var cache = {};
|
||
|
||
function padLeft(input, padding, length) {
|
||
var result = input;
|
||
|
||
var padLength = length - input.length;
|
||
for (var i = 0; i < padLength; i++) {
|
||
result = padding + result;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
function escape(ch) {
|
||
var charCode = ch.charCodeAt(0);
|
||
|
||
if (charCode <= 0xFF) {
|
||
var escapeChar = 'x';
|
||
var length = 2;
|
||
} else {
|
||
var escapeChar = 'u';
|
||
var length = 4;
|
||
}
|
||
|
||
return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
|
||
}
|
||
|
||
function quote(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(/\n/g, '\\n') // line feed
|
||
.replace(/[\x80-\uFFFF]/g, escape) // non-ASCII characters
|
||
+ '"';
|
||
}
|
||
|
||
function matchFailed(failure) {
|
||
if (pos < rightmostMatchFailuresPos) {
|
||
return;
|
||
}
|
||
|
||
if (pos > rightmostMatchFailuresPos) {
|
||
rightmostMatchFailuresPos = pos;
|
||
rightmostMatchFailuresExpected = [];
|
||
}
|
||
|
||
rightmostMatchFailuresExpected.push(failure);
|
||
}
|
||
|
||
function parse_grammar() {
|
||
var cacheKey = 'grammar@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result2 = parse___();
|
||
if (result2 !== null) {
|
||
var result6 = parse_initializer();
|
||
var result3 = result6 !== null ? result6 : '';
|
||
if (result3 !== null) {
|
||
var result5 = parse_rule();
|
||
if (result5 !== null) {
|
||
var result4 = [];
|
||
while (result5 !== null) {
|
||
result4.push(result5);
|
||
var result5 = parse_rule();
|
||
}
|
||
} else {
|
||
var result4 = null;
|
||
}
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(initializer, rules) {
|
||
var rulesConverted = {};
|
||
each(rules, function(rule) { rulesConverted[rule.name] = rule; });
|
||
|
||
return {
|
||
type: "grammar",
|
||
initializer: initializer !== "" ? initializer : null,
|
||
rules: rulesConverted,
|
||
startRule: rules[0].name
|
||
}
|
||
})(result1[1], result1[2])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_initializer() {
|
||
var cacheKey = 'initializer@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result2 = parse_action();
|
||
if (result2 !== null) {
|
||
var result4 = parse_semicolon();
|
||
var result3 = result4 !== null ? result4 : '';
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(code) {
|
||
return {
|
||
type: "initializer",
|
||
code: code
|
||
};
|
||
})(result1[0])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_rule() {
|
||
var cacheKey = 'rule@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result2 = parse_identifier();
|
||
if (result2 !== null) {
|
||
var result9 = parse_literal();
|
||
if (result9 !== null) {
|
||
var result3 = result9;
|
||
} else {
|
||
if (input.substr(pos, 0) === "") {
|
||
var result8 = "";
|
||
pos += 0;
|
||
} else {
|
||
var result8 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\"");
|
||
}
|
||
}
|
||
if (result8 !== null) {
|
||
var result3 = result8;
|
||
} else {
|
||
var result3 = null;;
|
||
};
|
||
}
|
||
if (result3 !== null) {
|
||
var result4 = parse_equals();
|
||
if (result4 !== null) {
|
||
var result5 = parse_choice();
|
||
if (result5 !== null) {
|
||
var result7 = parse_semicolon();
|
||
var result6 = result7 !== null ? result7 : '';
|
||
if (result6 !== null) {
|
||
var result1 = [result2, result3, result4, result5, result6];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(name, displayName, expression) {
|
||
return {
|
||
type: "rule",
|
||
name: name,
|
||
displayName: displayName !== "" ? displayName : null,
|
||
expression: expression
|
||
};
|
||
})(result1[0], result1[1], result1[3])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_choice() {
|
||
var cacheKey = 'choice@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result2 = parse_sequence();
|
||
if (result2 !== null) {
|
||
var result3 = [];
|
||
var savedPos1 = pos;
|
||
var result5 = parse_slash();
|
||
if (result5 !== null) {
|
||
var result6 = parse_sequence();
|
||
if (result6 !== null) {
|
||
var result4 = [result5, result6];
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
while (result4 !== null) {
|
||
result3.push(result4);
|
||
var savedPos1 = pos;
|
||
var result5 = parse_slash();
|
||
if (result5 !== null) {
|
||
var result6 = parse_sequence();
|
||
if (result6 !== null) {
|
||
var result4 = [result5, result6];
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(head, tail) {
|
||
if (tail.length > 0) {
|
||
var alternatives = [head].concat(map(
|
||
tail,
|
||
function(element) { return element[1]; }
|
||
));
|
||
return {
|
||
type: "choice",
|
||
alternatives: alternatives
|
||
}
|
||
} else {
|
||
return head;
|
||
}
|
||
})(result1[0], result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_sequence() {
|
||
var cacheKey = 'sequence@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result6 = [];
|
||
var result8 = parse_labeled();
|
||
while (result8 !== null) {
|
||
result6.push(result8);
|
||
var result8 = parse_labeled();
|
||
}
|
||
if (result6 !== null) {
|
||
var result7 = parse_action();
|
||
if (result7 !== null) {
|
||
var result5 = [result6, result7];
|
||
} else {
|
||
var result5 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result5 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result4 = result5 !== null
|
||
? (function(elements, code) {
|
||
var expression = elements.length != 1
|
||
? {
|
||
type: "sequence",
|
||
elements: elements
|
||
}
|
||
: elements[0];
|
||
return {
|
||
type: "action",
|
||
expression: expression,
|
||
code: code
|
||
};
|
||
})(result5[0], result5[1])
|
||
: null;
|
||
if (result4 !== null) {
|
||
var result0 = result4;
|
||
} else {
|
||
var result2 = [];
|
||
var result3 = parse_labeled();
|
||
while (result3 !== null) {
|
||
result2.push(result3);
|
||
var result3 = parse_labeled();
|
||
}
|
||
var result1 = result2 !== null
|
||
? (function(elements) {
|
||
return elements.length != 1
|
||
? {
|
||
type: "sequence",
|
||
elements: elements
|
||
}
|
||
: elements[0];
|
||
})(result2)
|
||
: null;
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_labeled() {
|
||
var cacheKey = 'labeled@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result4 = parse_identifier();
|
||
if (result4 !== null) {
|
||
var result5 = parse_colon();
|
||
if (result5 !== null) {
|
||
var result6 = parse_prefixed();
|
||
if (result6 !== null) {
|
||
var result3 = [result4, result5, result6];
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result2 = result3 !== null
|
||
? (function(label, expression) {
|
||
return {
|
||
type: "labeled",
|
||
label: label,
|
||
expression: expression
|
||
};
|
||
})(result3[0], result3[2])
|
||
: null;
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_prefixed();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_prefixed() {
|
||
var cacheKey = 'prefixed@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos3 = pos;
|
||
var result16 = parse_and();
|
||
if (result16 !== null) {
|
||
var result17 = parse_action();
|
||
if (result17 !== null) {
|
||
var result15 = [result16, result17];
|
||
} else {
|
||
var result15 = null;
|
||
pos = savedPos3;
|
||
}
|
||
} else {
|
||
var result15 = null;
|
||
pos = savedPos3;
|
||
}
|
||
var result14 = result15 !== null
|
||
? (function(code) {
|
||
return {
|
||
type: "semantic_and",
|
||
code: code
|
||
};
|
||
})(result15[1])
|
||
: null;
|
||
if (result14 !== null) {
|
||
var result0 = result14;
|
||
} else {
|
||
var savedPos2 = pos;
|
||
var result12 = parse_and();
|
||
if (result12 !== null) {
|
||
var result13 = parse_suffixed();
|
||
if (result13 !== null) {
|
||
var result11 = [result12, result13];
|
||
} else {
|
||
var result11 = null;
|
||
pos = savedPos2;
|
||
}
|
||
} else {
|
||
var result11 = null;
|
||
pos = savedPos2;
|
||
}
|
||
var result10 = result11 !== null
|
||
? (function(expression) {
|
||
return {
|
||
type: "simple_and",
|
||
expression: expression
|
||
};
|
||
})(result11[1])
|
||
: null;
|
||
if (result10 !== null) {
|
||
var result0 = result10;
|
||
} else {
|
||
var savedPos1 = pos;
|
||
var result8 = parse_not();
|
||
if (result8 !== null) {
|
||
var result9 = parse_action();
|
||
if (result9 !== null) {
|
||
var result7 = [result8, result9];
|
||
} else {
|
||
var result7 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result7 = null;
|
||
pos = savedPos1;
|
||
}
|
||
var result6 = result7 !== null
|
||
? (function(code) {
|
||
return {
|
||
type: "semantic_not",
|
||
code: code
|
||
};
|
||
})(result7[1])
|
||
: null;
|
||
if (result6 !== null) {
|
||
var result0 = result6;
|
||
} else {
|
||
var savedPos0 = pos;
|
||
var result4 = parse_not();
|
||
if (result4 !== null) {
|
||
var result5 = parse_suffixed();
|
||
if (result5 !== null) {
|
||
var result3 = [result4, result5];
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result2 = result3 !== null
|
||
? (function(expression) {
|
||
return {
|
||
type: "simple_not",
|
||
expression: expression
|
||
};
|
||
})(result3[1])
|
||
: null;
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_suffixed();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_suffixed() {
|
||
var cacheKey = 'suffixed@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos2 = pos;
|
||
var result12 = parse_primary();
|
||
if (result12 !== null) {
|
||
var result13 = parse_question();
|
||
if (result13 !== null) {
|
||
var result11 = [result12, result13];
|
||
} else {
|
||
var result11 = null;
|
||
pos = savedPos2;
|
||
}
|
||
} else {
|
||
var result11 = null;
|
||
pos = savedPos2;
|
||
}
|
||
var result10 = result11 !== null
|
||
? (function(expression) {
|
||
return {
|
||
type: "optional",
|
||
expression: expression
|
||
};
|
||
})(result11[0])
|
||
: null;
|
||
if (result10 !== null) {
|
||
var result0 = result10;
|
||
} else {
|
||
var savedPos1 = pos;
|
||
var result8 = parse_primary();
|
||
if (result8 !== null) {
|
||
var result9 = parse_star();
|
||
if (result9 !== null) {
|
||
var result7 = [result8, result9];
|
||
} else {
|
||
var result7 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result7 = null;
|
||
pos = savedPos1;
|
||
}
|
||
var result6 = result7 !== null
|
||
? (function(expression) {
|
||
return {
|
||
type: "zero_or_more",
|
||
expression: expression
|
||
};
|
||
})(result7[0])
|
||
: null;
|
||
if (result6 !== null) {
|
||
var result0 = result6;
|
||
} else {
|
||
var savedPos0 = pos;
|
||
var result4 = parse_primary();
|
||
if (result4 !== null) {
|
||
var result5 = parse_plus();
|
||
if (result5 !== null) {
|
||
var result3 = [result4, result5];
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result2 = result3 !== null
|
||
? (function(expression) {
|
||
return {
|
||
type: "one_or_more",
|
||
expression: expression
|
||
};
|
||
})(result3[0])
|
||
: null;
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_primary();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_primary() {
|
||
var cacheKey = 'primary@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos1 = pos;
|
||
var result13 = parse_identifier();
|
||
if (result13 !== null) {
|
||
var savedPos2 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var savedPos3 = pos;
|
||
var result19 = parse_literal();
|
||
if (result19 !== null) {
|
||
var result16 = result19;
|
||
} else {
|
||
if (input.substr(pos, 0) === "") {
|
||
var result18 = "";
|
||
pos += 0;
|
||
} else {
|
||
var result18 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\"");
|
||
}
|
||
}
|
||
if (result18 !== null) {
|
||
var result16 = result18;
|
||
} else {
|
||
var result16 = null;;
|
||
};
|
||
}
|
||
if (result16 !== null) {
|
||
var result17 = parse_equals();
|
||
if (result17 !== null) {
|
||
var result15 = [result16, result17];
|
||
} else {
|
||
var result15 = null;
|
||
pos = savedPos3;
|
||
}
|
||
} else {
|
||
var result15 = null;
|
||
pos = savedPos3;
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result15 === null) {
|
||
var result14 = '';
|
||
} else {
|
||
var result14 = null;
|
||
pos = savedPos2;
|
||
}
|
||
if (result14 !== null) {
|
||
var result12 = [result13, result14];
|
||
} else {
|
||
var result12 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result12 = null;
|
||
pos = savedPos1;
|
||
}
|
||
var result11 = result12 !== null
|
||
? (function(name) {
|
||
return {
|
||
type: "rule_ref",
|
||
name: name
|
||
};
|
||
})(result12[0])
|
||
: null;
|
||
if (result11 !== null) {
|
||
var result0 = result11;
|
||
} else {
|
||
var result10 = parse_literal();
|
||
var result9 = result10 !== null
|
||
? (function(value) {
|
||
return {
|
||
type: "literal",
|
||
value: value
|
||
};
|
||
})(result10)
|
||
: null;
|
||
if (result9 !== null) {
|
||
var result0 = result9;
|
||
} else {
|
||
var result8 = parse_dot();
|
||
var result7 = result8 !== null
|
||
? (function() { return { type: "any" }; })()
|
||
: null;
|
||
if (result7 !== null) {
|
||
var result0 = result7;
|
||
} else {
|
||
var result6 = parse_class();
|
||
if (result6 !== null) {
|
||
var result0 = result6;
|
||
} else {
|
||
var savedPos0 = pos;
|
||
var result3 = parse_lparen();
|
||
if (result3 !== null) {
|
||
var result4 = parse_choice();
|
||
if (result4 !== null) {
|
||
var result5 = parse_rparen();
|
||
if (result5 !== null) {
|
||
var result2 = [result3, result4, result5];
|
||
} else {
|
||
var result2 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result2 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result2 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result1 = result2 !== null
|
||
? (function(expression) { return expression; })(result2[1])
|
||
: null;
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_action() {
|
||
var cacheKey = 'action@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var savedPos0 = pos;
|
||
var result2 = parse_braced();
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(braced) { return braced.substr(1, braced.length - 2); })(result1[0])
|
||
: null;
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("action");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_braced() {
|
||
var cacheKey = 'braced@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "{") {
|
||
var result2 = "{";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"{\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = [];
|
||
var result7 = parse_braced();
|
||
if (result7 !== null) {
|
||
var result5 = result7;
|
||
} else {
|
||
var result6 = parse_nonBraceCharacter();
|
||
if (result6 !== null) {
|
||
var result5 = result6;
|
||
} else {
|
||
var result5 = null;;
|
||
};
|
||
}
|
||
while (result5 !== null) {
|
||
result3.push(result5);
|
||
var result7 = parse_braced();
|
||
if (result7 !== null) {
|
||
var result5 = result7;
|
||
} else {
|
||
var result6 = parse_nonBraceCharacter();
|
||
if (result6 !== null) {
|
||
var result5 = result6;
|
||
} else {
|
||
var result5 = null;;
|
||
};
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
if (input.substr(pos, 1) === "}") {
|
||
var result4 = "}";
|
||
pos += 1;
|
||
} else {
|
||
var result4 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"}\"");
|
||
}
|
||
}
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(parts) {
|
||
return "{" + parts.join("") + "}";
|
||
})(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_nonBraceCharacters() {
|
||
var cacheKey = 'nonBraceCharacters@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result2 = parse_nonBraceCharacter();
|
||
if (result2 !== null) {
|
||
var result1 = [];
|
||
while (result2 !== null) {
|
||
result1.push(result2);
|
||
var result2 = parse_nonBraceCharacter();
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(chars) { return chars.join(""); })(result1)
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_nonBraceCharacter() {
|
||
var cacheKey = 'nonBraceCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
if (input.substr(pos).match(/^[^{}]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[^{}]");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_equals() {
|
||
var cacheKey = 'equals@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "=") {
|
||
var result2 = "=";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"=\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "="; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_colon() {
|
||
var cacheKey = 'colon@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === ":") {
|
||
var result2 = ":";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\":\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return ":"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_semicolon() {
|
||
var cacheKey = 'semicolon@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === ";") {
|
||
var result2 = ";";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\";\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return ";"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_slash() {
|
||
var cacheKey = 'slash@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "/") {
|
||
var result2 = "/";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"/\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "/"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_and() {
|
||
var cacheKey = 'and@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "&") {
|
||
var result2 = "&";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"&\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "&"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_not() {
|
||
var cacheKey = 'not@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "!") {
|
||
var result2 = "!";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"!\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "!"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_question() {
|
||
var cacheKey = 'question@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "?") {
|
||
var result2 = "?";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"?\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "?"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_star() {
|
||
var cacheKey = 'star@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "*") {
|
||
var result2 = "*";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"*\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "*"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_plus() {
|
||
var cacheKey = 'plus@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "+") {
|
||
var result2 = "+";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"+\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "+"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_lparen() {
|
||
var cacheKey = 'lparen@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "(") {
|
||
var result2 = "(";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"(\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "("; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_rparen() {
|
||
var cacheKey = 'rparen@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === ")") {
|
||
var result2 = ")";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\")\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return ")"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_dot() {
|
||
var cacheKey = 'dot@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === ".") {
|
||
var result2 = ".";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\".\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "."; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_identifier() {
|
||
var cacheKey = 'identifier@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var savedPos0 = pos;
|
||
var result12 = parse_letter();
|
||
if (result12 !== null) {
|
||
var result2 = result12;
|
||
} else {
|
||
if (input.substr(pos, 1) === "_") {
|
||
var result11 = "_";
|
||
pos += 1;
|
||
} else {
|
||
var result11 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"_\"");
|
||
}
|
||
}
|
||
if (result11 !== null) {
|
||
var result2 = result11;
|
||
} else {
|
||
if (input.substr(pos, 1) === "$") {
|
||
var result10 = "$";
|
||
pos += 1;
|
||
} else {
|
||
var result10 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"$\"");
|
||
}
|
||
}
|
||
if (result10 !== null) {
|
||
var result2 = result10;
|
||
} else {
|
||
var result2 = null;;
|
||
};
|
||
};
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = [];
|
||
var result9 = parse_letter();
|
||
if (result9 !== null) {
|
||
var result5 = result9;
|
||
} else {
|
||
var result8 = parse_digit();
|
||
if (result8 !== null) {
|
||
var result5 = result8;
|
||
} else {
|
||
if (input.substr(pos, 1) === "_") {
|
||
var result7 = "_";
|
||
pos += 1;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"_\"");
|
||
}
|
||
}
|
||
if (result7 !== null) {
|
||
var result5 = result7;
|
||
} else {
|
||
if (input.substr(pos, 1) === "$") {
|
||
var result6 = "$";
|
||
pos += 1;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"$\"");
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result5 = result6;
|
||
} else {
|
||
var result5 = null;;
|
||
};
|
||
};
|
||
};
|
||
}
|
||
while (result5 !== null) {
|
||
result3.push(result5);
|
||
var result9 = parse_letter();
|
||
if (result9 !== null) {
|
||
var result5 = result9;
|
||
} else {
|
||
var result8 = parse_digit();
|
||
if (result8 !== null) {
|
||
var result5 = result8;
|
||
} else {
|
||
if (input.substr(pos, 1) === "_") {
|
||
var result7 = "_";
|
||
pos += 1;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"_\"");
|
||
}
|
||
}
|
||
if (result7 !== null) {
|
||
var result5 = result7;
|
||
} else {
|
||
if (input.substr(pos, 1) === "$") {
|
||
var result6 = "$";
|
||
pos += 1;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"$\"");
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result5 = result6;
|
||
} else {
|
||
var result5 = null;;
|
||
};
|
||
};
|
||
};
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result4 = parse___();
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(head, tail) {
|
||
return head + tail.join("");
|
||
})(result1[0], result1[1])
|
||
: null;
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("identifier");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_literal() {
|
||
var cacheKey = 'literal@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var savedPos0 = pos;
|
||
var result5 = parse_doubleQuotedLiteral();
|
||
if (result5 !== null) {
|
||
var result2 = result5;
|
||
} else {
|
||
var result4 = parse_singleQuotedLiteral();
|
||
if (result4 !== null) {
|
||
var result2 = result4;
|
||
} else {
|
||
var result2 = null;;
|
||
};
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse___();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(literal) { return literal; })(result1[0])
|
||
: null;
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("literal");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_doubleQuotedLiteral() {
|
||
var cacheKey = 'doubleQuotedLiteral@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "\"") {
|
||
var result2 = "\"";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\"\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = [];
|
||
var result5 = parse_doubleQuotedCharacter();
|
||
while (result5 !== null) {
|
||
result3.push(result5);
|
||
var result5 = parse_doubleQuotedCharacter();
|
||
}
|
||
if (result3 !== null) {
|
||
if (input.substr(pos, 1) === "\"") {
|
||
var result4 = "\"";
|
||
pos += 1;
|
||
} else {
|
||
var result4 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\"\"");
|
||
}
|
||
}
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(chars) { return chars.join(""); })(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_doubleQuotedCharacter() {
|
||
var cacheKey = 'doubleQuotedCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result6 = parse_simpleDoubleQuotedCharacter();
|
||
if (result6 !== null) {
|
||
var result0 = result6;
|
||
} else {
|
||
var result5 = parse_simpleEscapeSequence();
|
||
if (result5 !== null) {
|
||
var result0 = result5;
|
||
} else {
|
||
var result4 = parse_zeroEscapeSequence();
|
||
if (result4 !== null) {
|
||
var result0 = result4;
|
||
} else {
|
||
var result3 = parse_hexEscapeSequence();
|
||
if (result3 !== null) {
|
||
var result0 = result3;
|
||
} else {
|
||
var result2 = parse_unicodeEscapeSequence();
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_eolEscapeSequence();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_simpleDoubleQuotedCharacter() {
|
||
var cacheKey = 'simpleDoubleQuotedCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var savedPos1 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos, 1) === "\"") {
|
||
var result7 = "\"";
|
||
pos += 1;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\"\"");
|
||
}
|
||
}
|
||
if (result7 !== null) {
|
||
var result4 = result7;
|
||
} else {
|
||
if (input.substr(pos, 1) === "\\") {
|
||
var result6 = "\\";
|
||
pos += 1;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\\"");
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result4 = result6;
|
||
} else {
|
||
var result5 = parse_eolChar();
|
||
if (result5 !== null) {
|
||
var result4 = result5;
|
||
} else {
|
||
var result4 = null;;
|
||
};
|
||
};
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result4 === null) {
|
||
var result2 = '';
|
||
} else {
|
||
var result2 = null;
|
||
pos = savedPos1;
|
||
}
|
||
if (result2 !== null) {
|
||
if (input.length > pos) {
|
||
var result3 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result3 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(char_) { return char_; })(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_singleQuotedLiteral() {
|
||
var cacheKey = 'singleQuotedLiteral@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "'") {
|
||
var result2 = "'";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"'\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = [];
|
||
var result5 = parse_singleQuotedCharacter();
|
||
while (result5 !== null) {
|
||
result3.push(result5);
|
||
var result5 = parse_singleQuotedCharacter();
|
||
}
|
||
if (result3 !== null) {
|
||
if (input.substr(pos, 1) === "'") {
|
||
var result4 = "'";
|
||
pos += 1;
|
||
} else {
|
||
var result4 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"'\"");
|
||
}
|
||
}
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(chars) { return chars.join(""); })(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_singleQuotedCharacter() {
|
||
var cacheKey = 'singleQuotedCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result6 = parse_simpleSingleQuotedCharacter();
|
||
if (result6 !== null) {
|
||
var result0 = result6;
|
||
} else {
|
||
var result5 = parse_simpleEscapeSequence();
|
||
if (result5 !== null) {
|
||
var result0 = result5;
|
||
} else {
|
||
var result4 = parse_zeroEscapeSequence();
|
||
if (result4 !== null) {
|
||
var result0 = result4;
|
||
} else {
|
||
var result3 = parse_hexEscapeSequence();
|
||
if (result3 !== null) {
|
||
var result0 = result3;
|
||
} else {
|
||
var result2 = parse_unicodeEscapeSequence();
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_eolEscapeSequence();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_simpleSingleQuotedCharacter() {
|
||
var cacheKey = 'simpleSingleQuotedCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var savedPos1 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos, 1) === "'") {
|
||
var result7 = "'";
|
||
pos += 1;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"'\"");
|
||
}
|
||
}
|
||
if (result7 !== null) {
|
||
var result4 = result7;
|
||
} else {
|
||
if (input.substr(pos, 1) === "\\") {
|
||
var result6 = "\\";
|
||
pos += 1;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\\"");
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result4 = result6;
|
||
} else {
|
||
var result5 = parse_eolChar();
|
||
if (result5 !== null) {
|
||
var result4 = result5;
|
||
} else {
|
||
var result4 = null;;
|
||
};
|
||
};
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result4 === null) {
|
||
var result2 = '';
|
||
} else {
|
||
var result2 = null;
|
||
pos = savedPos1;
|
||
}
|
||
if (result2 !== null) {
|
||
if (input.length > pos) {
|
||
var result3 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result3 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(char_) { return char_; })(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_class() {
|
||
var cacheKey = 'class@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "[") {
|
||
var result2 = "[";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"[\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
if (input.substr(pos, 1) === "^") {
|
||
var result10 = "^";
|
||
pos += 1;
|
||
} else {
|
||
var result10 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"^\"");
|
||
}
|
||
}
|
||
var result3 = result10 !== null ? result10 : '';
|
||
if (result3 !== null) {
|
||
var result4 = [];
|
||
var result9 = parse_classCharacterRange();
|
||
if (result9 !== null) {
|
||
var result7 = result9;
|
||
} else {
|
||
var result8 = parse_classCharacter();
|
||
if (result8 !== null) {
|
||
var result7 = result8;
|
||
} else {
|
||
var result7 = null;;
|
||
};
|
||
}
|
||
while (result7 !== null) {
|
||
result4.push(result7);
|
||
var result9 = parse_classCharacterRange();
|
||
if (result9 !== null) {
|
||
var result7 = result9;
|
||
} else {
|
||
var result8 = parse_classCharacter();
|
||
if (result8 !== null) {
|
||
var result7 = result8;
|
||
} else {
|
||
var result7 = null;;
|
||
};
|
||
}
|
||
}
|
||
if (result4 !== null) {
|
||
if (input.substr(pos, 1) === "]") {
|
||
var result5 = "]";
|
||
pos += 1;
|
||
} else {
|
||
var result5 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"]\"");
|
||
}
|
||
}
|
||
if (result5 !== null) {
|
||
var result6 = parse___();
|
||
if (result6 !== null) {
|
||
var result1 = [result2, result3, result4, result5, result6];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(inverted, parts) {
|
||
var partsConverted = map(parts, function(part) { return part.data; });
|
||
var rawText = "["
|
||
+ inverted
|
||
+ map(parts, function(part) { return part.rawText; }).join("")
|
||
+ "]";
|
||
|
||
return {
|
||
type: "class",
|
||
inverted: inverted === "^",
|
||
parts: partsConverted,
|
||
// FIXME: Get the raw text from the input directly.
|
||
rawText: rawText
|
||
};
|
||
})(result1[1], result1[2])
|
||
: null;
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("character class");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_classCharacterRange() {
|
||
var cacheKey = 'classCharacterRange@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var result2 = parse_classCharacter();
|
||
if (result2 !== null) {
|
||
if (input.substr(pos, 1) === "-") {
|
||
var result3 = "-";
|
||
pos += 1;
|
||
} else {
|
||
var result3 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"-\"");
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result4 = parse_classCharacter();
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(begin, end) {
|
||
if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
|
||
throw new this.SyntaxError(
|
||
"Invalid character range: " + begin.rawText + "-" + end.rawText + "."
|
||
);
|
||
}
|
||
|
||
return {
|
||
data: [begin.data, end.data],
|
||
// FIXME: Get the raw text from the input directly.
|
||
rawText: begin.rawText + "-" + end.rawText
|
||
}
|
||
})(result1[0], result1[2])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_classCharacter() {
|
||
var cacheKey = 'classCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result1 = parse_bracketDelimitedCharacter();
|
||
var result0 = result1 !== null
|
||
? (function(char_) {
|
||
return {
|
||
data: char_,
|
||
// FIXME: Get the raw text from the input directly.
|
||
rawText: quoteForRegexpClass(char_)
|
||
};
|
||
})(result1)
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_bracketDelimitedCharacter() {
|
||
var cacheKey = 'bracketDelimitedCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result6 = parse_simpleBracketDelimitedCharacter();
|
||
if (result6 !== null) {
|
||
var result0 = result6;
|
||
} else {
|
||
var result5 = parse_simpleEscapeSequence();
|
||
if (result5 !== null) {
|
||
var result0 = result5;
|
||
} else {
|
||
var result4 = parse_zeroEscapeSequence();
|
||
if (result4 !== null) {
|
||
var result0 = result4;
|
||
} else {
|
||
var result3 = parse_hexEscapeSequence();
|
||
if (result3 !== null) {
|
||
var result0 = result3;
|
||
} else {
|
||
var result2 = parse_unicodeEscapeSequence();
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_eolEscapeSequence();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_simpleBracketDelimitedCharacter() {
|
||
var cacheKey = 'simpleBracketDelimitedCharacter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
var savedPos1 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos, 1) === "]") {
|
||
var result7 = "]";
|
||
pos += 1;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"]\"");
|
||
}
|
||
}
|
||
if (result7 !== null) {
|
||
var result4 = result7;
|
||
} else {
|
||
if (input.substr(pos, 1) === "\\") {
|
||
var result6 = "\\";
|
||
pos += 1;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\\"");
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result4 = result6;
|
||
} else {
|
||
var result5 = parse_eolChar();
|
||
if (result5 !== null) {
|
||
var result4 = result5;
|
||
} else {
|
||
var result4 = null;;
|
||
};
|
||
};
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result4 === null) {
|
||
var result2 = '';
|
||
} else {
|
||
var result2 = null;
|
||
pos = savedPos1;
|
||
}
|
||
if (result2 !== null) {
|
||
if (input.length > pos) {
|
||
var result3 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result3 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(char_) { return char_; })(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_simpleEscapeSequence() {
|
||
var cacheKey = 'simpleEscapeSequence@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "\\") {
|
||
var result2 = "\\";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var savedPos1 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var result9 = parse_digit();
|
||
if (result9 !== null) {
|
||
var result5 = result9;
|
||
} else {
|
||
if (input.substr(pos, 1) === "x") {
|
||
var result8 = "x";
|
||
pos += 1;
|
||
} else {
|
||
var result8 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"x\"");
|
||
}
|
||
}
|
||
if (result8 !== null) {
|
||
var result5 = result8;
|
||
} else {
|
||
if (input.substr(pos, 1) === "u") {
|
||
var result7 = "u";
|
||
pos += 1;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"u\"");
|
||
}
|
||
}
|
||
if (result7 !== null) {
|
||
var result5 = result7;
|
||
} else {
|
||
var result6 = parse_eolChar();
|
||
if (result6 !== null) {
|
||
var result5 = result6;
|
||
} else {
|
||
var result5 = null;;
|
||
};
|
||
};
|
||
};
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result5 === null) {
|
||
var result3 = '';
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos1;
|
||
}
|
||
if (result3 !== null) {
|
||
if (input.length > pos) {
|
||
var result4 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result4 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(char_) {
|
||
return char_
|
||
.replace("b", "\b")
|
||
.replace("f", "\f")
|
||
.replace("n", "\n")
|
||
.replace("r", "\r")
|
||
.replace("t", "\t")
|
||
.replace("v", "\x0B") // IE does not recognize "\v".
|
||
})(result1[2])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_zeroEscapeSequence() {
|
||
var cacheKey = 'zeroEscapeSequence@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 2) === "\\0") {
|
||
var result2 = "\\0";
|
||
pos += 2;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\0\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var savedPos1 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var result4 = parse_digit();
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result4 === null) {
|
||
var result3 = '';
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos1;
|
||
}
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function() { return "\0"; })()
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_hexEscapeSequence() {
|
||
var cacheKey = 'hexEscapeSequence@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 2) === "\\x") {
|
||
var result2 = "\\x";
|
||
pos += 2;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\x\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse_hexDigit();
|
||
if (result3 !== null) {
|
||
var result4 = parse_hexDigit();
|
||
if (result4 !== null) {
|
||
var result1 = [result2, result3, result4];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(h1, h2) {
|
||
return String.fromCharCode(parseInt("0x" + h1 + h2));
|
||
})(result1[1], result1[2])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_unicodeEscapeSequence() {
|
||
var cacheKey = 'unicodeEscapeSequence@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 2) === "\\u") {
|
||
var result2 = "\\u";
|
||
pos += 2;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\u\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse_hexDigit();
|
||
if (result3 !== null) {
|
||
var result4 = parse_hexDigit();
|
||
if (result4 !== null) {
|
||
var result5 = parse_hexDigit();
|
||
if (result5 !== null) {
|
||
var result6 = parse_hexDigit();
|
||
if (result6 !== null) {
|
||
var result1 = [result2, result3, result4, result5, result6];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(h1, h2, h3, h4) {
|
||
return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
|
||
})(result1[1], result1[2], result1[3], result1[4])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_eolEscapeSequence() {
|
||
var cacheKey = 'eolEscapeSequence@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 1) === "\\") {
|
||
var result2 = "\\";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\\\\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result3 = parse_eol();
|
||
if (result3 !== null) {
|
||
var result1 = [result2, result3];
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result1 = null;
|
||
pos = savedPos0;
|
||
}
|
||
var result0 = result1 !== null
|
||
? (function(eol) { return eol; })(result1[1])
|
||
: null;
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_digit() {
|
||
var cacheKey = 'digit@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
if (input.substr(pos).match(/^[0-9]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[0-9]");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_hexDigit() {
|
||
var cacheKey = 'hexDigit@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
if (input.substr(pos).match(/^[0-9a-fA-F]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[0-9a-fA-F]");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_letter() {
|
||
var cacheKey = 'letter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result2 = parse_lowerCaseLetter();
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_upperCaseLetter();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_lowerCaseLetter() {
|
||
var cacheKey = 'lowerCaseLetter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
if (input.substr(pos).match(/^[a-z]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[a-z]");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_upperCaseLetter() {
|
||
var cacheKey = 'upperCaseLetter@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
if (input.substr(pos).match(/^[A-Z]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[A-Z]");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse___() {
|
||
var cacheKey = '__@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var result0 = [];
|
||
var result4 = parse_whitespace();
|
||
if (result4 !== null) {
|
||
var result1 = result4;
|
||
} else {
|
||
var result3 = parse_eol();
|
||
if (result3 !== null) {
|
||
var result1 = result3;
|
||
} else {
|
||
var result2 = parse_comment();
|
||
if (result2 !== null) {
|
||
var result1 = result2;
|
||
} else {
|
||
var result1 = null;;
|
||
};
|
||
};
|
||
}
|
||
while (result1 !== null) {
|
||
result0.push(result1);
|
||
var result4 = parse_whitespace();
|
||
if (result4 !== null) {
|
||
var result1 = result4;
|
||
} else {
|
||
var result3 = parse_eol();
|
||
if (result3 !== null) {
|
||
var result1 = result3;
|
||
} else {
|
||
var result2 = parse_comment();
|
||
if (result2 !== null) {
|
||
var result1 = result2;
|
||
} else {
|
||
var result1 = null;;
|
||
};
|
||
};
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_comment() {
|
||
var cacheKey = 'comment@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var result2 = parse_singleLineComment();
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
var result1 = parse_multiLineComment();
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
}
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("comment");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_singleLineComment() {
|
||
var cacheKey = 'singleLineComment@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 2) === "//") {
|
||
var result1 = "//";
|
||
pos += 2;
|
||
} else {
|
||
var result1 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"//\"");
|
||
}
|
||
}
|
||
if (result1 !== null) {
|
||
var result2 = [];
|
||
var savedPos1 = pos;
|
||
var savedPos2 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var result6 = parse_eolChar();
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result6 === null) {
|
||
var result4 = '';
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos2;
|
||
}
|
||
if (result4 !== null) {
|
||
if (input.length > pos) {
|
||
var result5 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result5 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result5 !== null) {
|
||
var result3 = [result4, result5];
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos1;
|
||
}
|
||
while (result3 !== null) {
|
||
result2.push(result3);
|
||
var savedPos1 = pos;
|
||
var savedPos2 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
var result6 = parse_eolChar();
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result6 === null) {
|
||
var result4 = '';
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos2;
|
||
}
|
||
if (result4 !== null) {
|
||
if (input.length > pos) {
|
||
var result5 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result5 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result5 !== null) {
|
||
var result3 = [result4, result5];
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result3 = null;
|
||
pos = savedPos1;
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result0 = [result1, result2];
|
||
} else {
|
||
var result0 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result0 = null;
|
||
pos = savedPos0;
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_multiLineComment() {
|
||
var cacheKey = 'multiLineComment@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
var savedPos0 = pos;
|
||
if (input.substr(pos, 2) === "/*") {
|
||
var result1 = "/*";
|
||
pos += 2;
|
||
} else {
|
||
var result1 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"/*\"");
|
||
}
|
||
}
|
||
if (result1 !== null) {
|
||
var result2 = [];
|
||
var savedPos1 = pos;
|
||
var savedPos2 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos, 2) === "*/") {
|
||
var result7 = "*/";
|
||
pos += 2;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"*/\"");
|
||
}
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result7 === null) {
|
||
var result5 = '';
|
||
} else {
|
||
var result5 = null;
|
||
pos = savedPos2;
|
||
}
|
||
if (result5 !== null) {
|
||
if (input.length > pos) {
|
||
var result6 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result4 = [result5, result6];
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
while (result4 !== null) {
|
||
result2.push(result4);
|
||
var savedPos1 = pos;
|
||
var savedPos2 = pos;
|
||
var savedReportMatchFailuresVar0 = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos, 2) === "*/") {
|
||
var result7 = "*/";
|
||
pos += 2;
|
||
} else {
|
||
var result7 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"*/\"");
|
||
}
|
||
}
|
||
reportMatchFailures = savedReportMatchFailuresVar0;
|
||
if (result7 === null) {
|
||
var result5 = '';
|
||
} else {
|
||
var result5 = null;
|
||
pos = savedPos2;
|
||
}
|
||
if (result5 !== null) {
|
||
if (input.length > pos) {
|
||
var result6 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result6 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed('any character');
|
||
}
|
||
}
|
||
if (result6 !== null) {
|
||
var result4 = [result5, result6];
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
} else {
|
||
var result4 = null;
|
||
pos = savedPos1;
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
if (input.substr(pos, 2) === "*/") {
|
||
var result3 = "*/";
|
||
pos += 2;
|
||
} else {
|
||
var result3 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"*/\"");
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result0 = [result1, result2, result3];
|
||
} else {
|
||
var result0 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result0 = null;
|
||
pos = savedPos0;
|
||
}
|
||
} else {
|
||
var result0 = null;
|
||
pos = savedPos0;
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_eol() {
|
||
var cacheKey = 'eol@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos, 1) === "\n") {
|
||
var result5 = "\n";
|
||
pos += 1;
|
||
} else {
|
||
var result5 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\n\"");
|
||
}
|
||
}
|
||
if (result5 !== null) {
|
||
var result0 = result5;
|
||
} else {
|
||
if (input.substr(pos, 2) === "\r\n") {
|
||
var result4 = "\r\n";
|
||
pos += 2;
|
||
} else {
|
||
var result4 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\r\\n\"");
|
||
}
|
||
}
|
||
if (result4 !== null) {
|
||
var result0 = result4;
|
||
} else {
|
||
if (input.substr(pos, 1) === "\r") {
|
||
var result3 = "\r";
|
||
pos += 1;
|
||
} else {
|
||
var result3 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\r\"");
|
||
}
|
||
}
|
||
if (result3 !== null) {
|
||
var result0 = result3;
|
||
} else {
|
||
if (input.substr(pos, 1) === "\u2028") {
|
||
var result2 = "\u2028";
|
||
pos += 1;
|
||
} else {
|
||
var result2 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\u2028\"");
|
||
}
|
||
}
|
||
if (result2 !== null) {
|
||
var result0 = result2;
|
||
} else {
|
||
if (input.substr(pos, 1) === "\u2029") {
|
||
var result1 = "\u2029";
|
||
pos += 1;
|
||
} else {
|
||
var result1 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("\"\\u2029\"");
|
||
}
|
||
}
|
||
if (result1 !== null) {
|
||
var result0 = result1;
|
||
} else {
|
||
var result0 = null;;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("end of line");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_eolChar() {
|
||
var cacheKey = 'eolChar@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
|
||
if (input.substr(pos).match(/^[\n\r\u2028\u2029]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[\\n\\r\\u2028\\u2029]");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function parse_whitespace() {
|
||
var cacheKey = 'whitespace@' + pos;
|
||
var cachedResult = cache[cacheKey];
|
||
if (cachedResult) {
|
||
pos = cachedResult.nextPos;
|
||
return cachedResult.result;
|
||
}
|
||
|
||
var savedReportMatchFailures = reportMatchFailures;
|
||
reportMatchFailures = false;
|
||
if (input.substr(pos).match(/^[ <20><>\xA0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]/) !== null) {
|
||
var result0 = input.charAt(pos);
|
||
pos++;
|
||
} else {
|
||
var result0 = null;
|
||
if (reportMatchFailures) {
|
||
matchFailed("[ <20><>\\xA0\\uFEFF\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]");
|
||
}
|
||
}
|
||
reportMatchFailures = savedReportMatchFailures;
|
||
if (reportMatchFailures && result0 === null) {
|
||
matchFailed("whitespace");
|
||
}
|
||
|
||
cache[cacheKey] = {
|
||
nextPos: pos,
|
||
result: result0
|
||
};
|
||
return result0;
|
||
}
|
||
|
||
function buildErrorMessage() {
|
||
function buildExpected(failuresExpected) {
|
||
failuresExpected.sort();
|
||
|
||
var lastFailure = null;
|
||
var failuresExpectedUnique = [];
|
||
for (var i = 0; i < failuresExpected.length; i++) {
|
||
if (failuresExpected[i] !== lastFailure) {
|
||
failuresExpectedUnique.push(failuresExpected[i]);
|
||
lastFailure = failuresExpected[i];
|
||
}
|
||
}
|
||
|
||
switch (failuresExpectedUnique.length) {
|
||
case 0:
|
||
return 'end of input';
|
||
case 1:
|
||
return failuresExpectedUnique[0];
|
||
default:
|
||
return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ')
|
||
+ ' or '
|
||
+ failuresExpectedUnique[failuresExpectedUnique.length - 1];
|
||
}
|
||
}
|
||
|
||
var expected = buildExpected(rightmostMatchFailuresExpected);
|
||
var actualPos = Math.max(pos, rightmostMatchFailuresPos);
|
||
var actual = actualPos < input.length
|
||
? quote(input.charAt(actualPos))
|
||
: '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 line = 1;
|
||
var column = 1;
|
||
var seenCR = false;
|
||
|
||
for (var i = 0; i < rightmostMatchFailuresPos; 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 result = parseFunctions[startRule]();
|
||
|
||
/*
|
||
* The parser is now in one of the following three states:
|
||
*
|
||
* 1. The parser successfully parsed the whole input.
|
||
*
|
||
* - |result !== null|
|
||
* - |pos === input.length|
|
||
* - |rightmostMatchFailuresExpected| may or may not contain something
|
||
*
|
||
* 2. The parser successfully parsed only a part of the input.
|
||
*
|
||
* - |result !== null|
|
||
* - |pos < input.length|
|
||
* - |rightmostMatchFailuresExpected| may or may not contain something
|
||
*
|
||
* 3. The parser did not successfully parse any part of the input.
|
||
*
|
||
* - |result === null|
|
||
* - |pos === 0|
|
||
* - |rightmostMatchFailuresExpected| contains at least one failure
|
||
*
|
||
* All code following this comment (including called functions) must
|
||
* handle these states.
|
||
*/
|
||
if (result === null || pos !== input.length) {
|
||
var errorPosition = computeErrorPosition();
|
||
throw new this.SyntaxError(
|
||
buildErrorMessage(),
|
||
errorPosition.line,
|
||
errorPosition.column
|
||
);
|
||
}
|
||
|
||
return result;
|
||
},
|
||
|
||
/* Returns the parser source code. */
|
||
toSource: function() { return this._source; }
|
||
};
|
||
|
||
/* Thrown when a parser encounters a syntax error. */
|
||
|
||
result.SyntaxError = function(message, line, column) {
|
||
this.name = 'SyntaxError';
|
||
this.message = message;
|
||
this.line = line;
|
||
this.column = column;
|
||
};
|
||
|
||
result.SyntaxError.prototype = Error.prototype;
|
||
|
||
return result;
|
||
})();
|
||
PEG.compiler = {
|
||
/*
|
||
* Generates a parser from a specified grammar AST. Throws |PEG.GrammarError|
|
||
* if the AST contains a semantic error. Note that not all errors are detected
|
||
* during the generation and some may protrude to the generated parser and
|
||
* cause its malfunction.
|
||
*/
|
||
compile: function(ast) {
|
||
var CHECK_NAMES = [
|
||
"missingReferencedRules",
|
||
"leftRecursion"
|
||
];
|
||
|
||
var PASS_NAMES = [
|
||
"proxyRules"
|
||
];
|
||
|
||
for (var i = 0; i < CHECK_NAMES.length; i++) {
|
||
this.checks[CHECK_NAMES[i]](ast);
|
||
}
|
||
|
||
for (var i = 0; i < PASS_NAMES.length; i++) {
|
||
ast = this.passes[PASS_NAMES[i]](ast);
|
||
}
|
||
|
||
var source = this.emitter(ast);
|
||
//console.log(source);
|
||
var result = eval(source);
|
||
result._source = source;
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
/*
|
||
* Checks made on the grammar AST before compilation. Each check is a function
|
||
* that is passed the AST and does not return anything. If the check passes, the
|
||
* function does not do anything special, otherwise it throws
|
||
* |PEG.GrammarError|. The order in which the checks are run is specified in
|
||
* |PEG.compiler.compile| and should be the same as the order of definitions
|
||
* here.
|
||
*/
|
||
PEG.compiler.checks = {
|
||
/* Checks that all referenced rules exist. */
|
||
missingReferencedRules: function(ast) {
|
||
function nop() {}
|
||
|
||
function checkExpression(node) { check(node.expression); }
|
||
|
||
function checkSubnodes(propertyName) {
|
||
return function(node) { each(node[propertyName], check); };
|
||
}
|
||
|
||
var check = buildNodeVisitor({
|
||
grammar:
|
||
function(node) {
|
||
for (var name in node.rules) {
|
||
check(node.rules[name]);
|
||
}
|
||
},
|
||
|
||
rule: checkExpression,
|
||
choice: checkSubnodes("alternatives"),
|
||
sequence: checkSubnodes("elements"),
|
||
labeled: checkExpression,
|
||
simple_and: checkExpression,
|
||
simple_not: checkExpression,
|
||
semantic_and: nop,
|
||
semantic_not: nop,
|
||
optional: checkExpression,
|
||
zero_or_more: checkExpression,
|
||
one_or_more: checkExpression,
|
||
action: checkExpression,
|
||
|
||
rule_ref:
|
||
function(node) {
|
||
if (ast.rules[node.name] === undefined) {
|
||
throw new PEG.GrammarError(
|
||
"Referenced rule \"" + node.name + "\" does not exist."
|
||
);
|
||
}
|
||
},
|
||
|
||
literal: nop,
|
||
any: nop,
|
||
"class": nop
|
||
});
|
||
|
||
check(ast);
|
||
},
|
||
|
||
/* Checks that no left recursion is present. */
|
||
leftRecursion: function(ast) {
|
||
function nop() {}
|
||
|
||
function checkExpression(node, appliedRules) {
|
||
check(node.expression, appliedRules);
|
||
}
|
||
|
||
var check = buildNodeVisitor({
|
||
grammar:
|
||
function(node, appliedRules) {
|
||
for (var name in node.rules) {
|
||
check(node.rules[name], appliedRules);
|
||
}
|
||
},
|
||
|
||
rule:
|
||
function(node, appliedRules) {
|
||
check(node.expression, appliedRules.concat(node.name));
|
||
},
|
||
|
||
choice:
|
||
function(node, appliedRules) {
|
||
each(node.alternatives, function(alternative) {
|
||
check(alternative, appliedRules);
|
||
});
|
||
},
|
||
|
||
sequence:
|
||
function(node, appliedRules) {
|
||
if (node.elements.length > 0) {
|
||
check(node.elements[0], appliedRules);
|
||
}
|
||
},
|
||
|
||
labeled: checkExpression,
|
||
simple_and: checkExpression,
|
||
simple_not: checkExpression,
|
||
semantic_and: nop,
|
||
semantic_not: nop,
|
||
optional: checkExpression,
|
||
zero_or_more: checkExpression,
|
||
one_or_more: checkExpression,
|
||
action: checkExpression,
|
||
|
||
rule_ref:
|
||
function(node, appliedRules) {
|
||
if (contains(appliedRules, node.name)) {
|
||
throw new PEG.GrammarError(
|
||
"Left recursion detected for rule \"" + node.name + "\"."
|
||
);
|
||
}
|
||
check(ast.rules[node.name], appliedRules);
|
||
},
|
||
|
||
literal: nop,
|
||
any: nop,
|
||
"class": nop
|
||
});
|
||
|
||
check(ast, []);
|
||
}
|
||
};
|
||
/*
|
||
* Optimalization passes made on the grammar AST before compilation. Each pass
|
||
* is a function that is passed the AST and returns a new AST. The AST can be
|
||
* modified in-place by the pass. The order in which the passes are run is
|
||
* specified in |PEG.compiler.compile| and should be the same as the order of
|
||
* definitions here.
|
||
*/
|
||
PEG.compiler.passes = {
|
||
/*
|
||
* Removes proxy rules -- that is, rules that only delegate to other rule.
|
||
*/
|
||
proxyRules: function(ast) {
|
||
function isProxyRule(node) {
|
||
return node.type === "rule" && node.expression.type === "rule_ref";
|
||
}
|
||
|
||
function replaceRuleRefs(ast, from, to) {
|
||
function nop() {}
|
||
|
||
function replaceInExpression(node, from, to) {
|
||
replace(node.expression, from, to);
|
||
}
|
||
|
||
function replaceInSubnodes(propertyName) {
|
||
return function(node, from, to) {
|
||
each(node[propertyName], function(subnode) {
|
||
replace(subnode, from, to);
|
||
});
|
||
};
|
||
}
|
||
|
||
var replace = buildNodeVisitor({
|
||
grammar:
|
||
function(node, from, to) {
|
||
for (var name in node.rules) {
|
||
replace(node.rules[name], from, to);
|
||
}
|
||
},
|
||
|
||
rule: replaceInExpression,
|
||
choice: replaceInSubnodes("alternatives"),
|
||
sequence: replaceInSubnodes("elements"),
|
||
labeled: replaceInExpression,
|
||
simple_and: replaceInExpression,
|
||
simple_not: replaceInExpression,
|
||
semantic_and: nop,
|
||
semantic_not: nop,
|
||
optional: replaceInExpression,
|
||
zero_or_more: replaceInExpression,
|
||
one_or_more: replaceInExpression,
|
||
action: replaceInExpression,
|
||
|
||
rule_ref:
|
||
function(node, from, to) {
|
||
if (node.name === from) {
|
||
node.name = to;
|
||
}
|
||
},
|
||
|
||
literal: nop,
|
||
any: nop,
|
||
"class": nop
|
||
});
|
||
|
||
replace(ast, from, to);
|
||
}
|
||
|
||
for (var name in ast.rules) {
|
||
if (isProxyRule(ast.rules[name])) {
|
||
replaceRuleRefs(ast, ast.rules[name].name, ast.rules[name].expression.name);
|
||
if (name === ast.startRule) {
|
||
ast.startRule = ast.rules[name].expression.name;
|
||
}
|
||
delete ast.rules[name];
|
||
}
|
||
}
|
||
|
||
return ast;
|
||
}
|
||
};
|
||
/* Emits the generated code for the AST. */
|
||
PEG.compiler.emitter = function(ast) {
|
||
/*
|
||
* Takes parts of code, interpolates variables inside them and joins them with
|
||
* a newline.
|
||
*
|
||
* Variables are delimited with "${" and "}" and their names must be valid
|
||
* identifiers (i.e. they must match [a-zA-Z_][a-zA-Z0-9_]*). Variable values
|
||
* are specified as properties of the last parameter (if this is an object,
|
||
* otherwise empty variable set is assumed). Undefined variables result in
|
||
* throwing |Error|.
|
||
*
|
||
* There can be a filter specified after the variable name, prefixed with "|".
|
||
* The filter name must be a valid identifier. The only recognized filter
|
||
* right now is "string", which quotes the variable value as a JavaScript
|
||
* string. Unrecognized filters result in throwing |Error|.
|
||
*
|
||
* If any part has multiple lines and the first line is indented by some
|
||
* amount of whitespace (as defined by the /\s+/ JavaScript regular
|
||
* expression), second to last lines are indented by the same amount of
|
||
* whitespace. This results in nicely indented multiline code in variables
|
||
* without making the templates look ugly.
|
||
*
|
||
* Examples:
|
||
*
|
||
* formatCode("foo", "bar"); // "foo\nbar"
|
||
* formatCode("foo", "${bar}", { bar: "baz" }); // "foo\nbaz"
|
||
* formatCode("foo", "${bar}"); // throws Error
|
||
* formatCode("foo", "${bar|string}", { bar: "baz" }); // "foo\n\"baz\""
|
||
* formatCode("foo", "${bar|eeek}", { bar: "baz" }); // throws Error
|
||
* formatCode("foo", "${bar}", { bar: " baz\nqux" }); // "foo\n baz\n qux"
|
||
*/
|
||
function formatCode() {
|
||
function interpolateVariablesInParts(parts) {
|
||
return map(parts, function(part) {
|
||
return part.replace(
|
||
/\$\{([a-zA-Z_][a-zA-Z0-9_]*)(\|([a-zA-Z_][a-zA-Z0-9_]*))?\}/g,
|
||
function(match, name, dummy, filter) {
|
||
var value = vars[name];
|
||
if (value === undefined) {
|
||
throw new Error("Undefined variable: \"" + name + "\".");
|
||
}
|
||
|
||
if (filter !== undefined && filter != "") { // JavaScript engines differ here.
|
||
if (filter === "string") {
|
||
return quote(value);
|
||
} else {
|
||
throw new Error("Unrecognized filter: \"" + filter + "\".");
|
||
}
|
||
} else {
|
||
return value;
|
||
}
|
||
}
|
||
);
|
||
});
|
||
}
|
||
|
||
function indentMultilineParts(parts) {
|
||
return map(parts, function(part) {
|
||
if (!/\n/.test(part)) { return part; }
|
||
|
||
var firstLineWhitespacePrefix = part.match(/^\s*/)[0];
|
||
var lines = part.split("\n");
|
||
var linesIndented = [lines[0]].concat(
|
||
map(lines.slice(1), function(line) {
|
||
return firstLineWhitespacePrefix + line;
|
||
})
|
||
);
|
||
return linesIndented.join("\n");
|
||
});
|
||
}
|
||
|
||
var args = Array.prototype.slice.call(arguments);
|
||
var vars = args[args.length - 1] instanceof Object ? args.pop() : {};
|
||
|
||
return indentMultilineParts(interpolateVariablesInParts(args)).join("\n");
|
||
};
|
||
|
||
/* Unique ID generator. */
|
||
var UID = {
|
||
_counters: {},
|
||
|
||
next: function(prefix) {
|
||
this._counters[prefix] = this._counters[prefix] || 0;
|
||
return prefix + this._counters[prefix]++;
|
||
},
|
||
|
||
reset: function() {
|
||
this._counters = {};
|
||
}
|
||
};
|
||
|
||
var emit = buildNodeVisitor({
|
||
grammar: function(node) {
|
||
var initializerCode = node.initializer !== null
|
||
? emit(node.initializer)
|
||
: "";
|
||
|
||
var parseFunctionTableItems = [];
|
||
for (var name in node.rules) {
|
||
parseFunctionTableItems.push(quote(name) + ": parse_" + name);
|
||
}
|
||
parseFunctionTableItems.sort();
|
||
|
||
var parseFunctionDefinitions = [];
|
||
for (var name in node.rules) {
|
||
parseFunctionDefinitions.push(emit(node.rules[name]));
|
||
}
|
||
|
||
return formatCode(
|
||
"(function(){",
|
||
" /* Generated by PEG.js 0.6.1 (http://pegjs.majda.cz/). */",
|
||
" ",
|
||
" var result = {",
|
||
" /*",
|
||
" * 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, startRule) {",
|
||
" var parseFunctions = {",
|
||
" ${parseFunctionTableItems}",
|
||
" };",
|
||
" ",
|
||
" if (startRule !== undefined) {",
|
||
" if (parseFunctions[startRule] === undefined) {",
|
||
" throw new Error(\"Invalid rule name: \" + quote(startRule) + \".\");",
|
||
" }",
|
||
" } else {",
|
||
" startRule = ${startRule|string};",
|
||
" }",
|
||
" ",
|
||
" var pos = 0;",
|
||
" var reportMatchFailures = true;",
|
||
" var rightmostMatchFailuresPos = 0;",
|
||
" var rightmostMatchFailuresExpected = [];",
|
||
" var cache = {};",
|
||
" ",
|
||
/* This needs to be in sync with |padLeft| in utils.js. */
|
||
" function padLeft(input, padding, length) {",
|
||
" var result = input;",
|
||
" ",
|
||
" var padLength = length - input.length;",
|
||
" for (var i = 0; i < padLength; i++) {",
|
||
" result = padding + result;",
|
||
" }",
|
||
" ",
|
||
" return result;",
|
||
" }",
|
||
" ",
|
||
/* This needs to be in sync with |escape| in utils.js. */
|
||
" function escape(ch) {",
|
||
" var charCode = ch.charCodeAt(0);",
|
||
" ",
|
||
" if (charCode <= 0xFF) {",
|
||
" var escapeChar = 'x';",
|
||
" var length = 2;",
|
||
" } else {",
|
||
" var escapeChar = 'u';",
|
||
" var length = 4;",
|
||
" }",
|
||
" ",
|
||
" return '\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);",
|
||
" }",
|
||
" ",
|
||
/* This needs to be in sync with |quote| in utils.js. */
|
||
" function quote(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(/\\n/g, '\\\\n') // line feed",
|
||
" .replace(/[\\x80-\\uFFFF]/g, escape) // non-ASCII characters",
|
||
" + '\"';",
|
||
" }",
|
||
" ",
|
||
" function matchFailed(failure) {",
|
||
" if (pos < rightmostMatchFailuresPos) {",
|
||
" return;",
|
||
" }",
|
||
" ",
|
||
" if (pos > rightmostMatchFailuresPos) {",
|
||
" rightmostMatchFailuresPos = pos;",
|
||
" rightmostMatchFailuresExpected = [];",
|
||
" }",
|
||
" ",
|
||
" rightmostMatchFailuresExpected.push(failure);",
|
||
" }",
|
||
" ",
|
||
" ${parseFunctionDefinitions}",
|
||
" ",
|
||
" function buildErrorMessage() {",
|
||
" function buildExpected(failuresExpected) {",
|
||
" failuresExpected.sort();",
|
||
" ",
|
||
" var lastFailure = null;",
|
||
" var failuresExpectedUnique = [];",
|
||
" for (var i = 0; i < failuresExpected.length; i++) {",
|
||
" if (failuresExpected[i] !== lastFailure) {",
|
||
" failuresExpectedUnique.push(failuresExpected[i]);",
|
||
" lastFailure = failuresExpected[i];",
|
||
" }",
|
||
" }",
|
||
" ",
|
||
" switch (failuresExpectedUnique.length) {",
|
||
" case 0:",
|
||
" return 'end of input';",
|
||
" case 1:",
|
||
" return failuresExpectedUnique[0];",
|
||
" default:",
|
||
" return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ')",
|
||
" + ' or '",
|
||
" + failuresExpectedUnique[failuresExpectedUnique.length - 1];",
|
||
" }",
|
||
" }",
|
||
" ",
|
||
" var expected = buildExpected(rightmostMatchFailuresExpected);",
|
||
" var actualPos = Math.max(pos, rightmostMatchFailuresPos);",
|
||
" var actual = actualPos < input.length",
|
||
" ? quote(input.charAt(actualPos))",
|
||
" : '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 line = 1;",
|
||
" var column = 1;",
|
||
" var seenCR = false;",
|
||
" ",
|
||
" for (var i = 0; i < rightmostMatchFailuresPos; 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 };",
|
||
" }",
|
||
" ",
|
||
" ${initializerCode}",
|
||
" ",
|
||
" var result = parseFunctions[startRule]();",
|
||
" ",
|
||
" /*",
|
||
" * The parser is now in one of the following three states:",
|
||
" *",
|
||
" * 1. The parser successfully parsed the whole input.",
|
||
" *",
|
||
" * - |result !== null|",
|
||
" * - |pos === input.length|",
|
||
" * - |rightmostMatchFailuresExpected| may or may not contain something",
|
||
" *",
|
||
" * 2. The parser successfully parsed only a part of the input.",
|
||
" *",
|
||
" * - |result !== null|",
|
||
" * - |pos < input.length|",
|
||
" * - |rightmostMatchFailuresExpected| may or may not contain something",
|
||
" *",
|
||
" * 3. The parser did not successfully parse any part of the input.",
|
||
" *",
|
||
" * - |result === null|",
|
||
" * - |pos === 0|",
|
||
" * - |rightmostMatchFailuresExpected| contains at least one failure",
|
||
" *",
|
||
" * All code following this comment (including called functions) must",
|
||
" * handle these states.",
|
||
" */",
|
||
" if (result === null || pos !== input.length) {",
|
||
" var errorPosition = computeErrorPosition();",
|
||
" throw new this.SyntaxError(",
|
||
" buildErrorMessage(),",
|
||
" errorPosition.line,",
|
||
" errorPosition.column",
|
||
" );",
|
||
" }",
|
||
" ",
|
||
" return result;",
|
||
" },",
|
||
" ",
|
||
" /* Returns the parser source code. */",
|
||
" toSource: function() { return this._source; }",
|
||
" };",
|
||
" ",
|
||
" /* Thrown when a parser encounters a syntax error. */",
|
||
" ",
|
||
" result.SyntaxError = function(message, line, column) {",
|
||
" this.name = 'SyntaxError';",
|
||
" this.message = message;",
|
||
" this.line = line;",
|
||
" this.column = column;",
|
||
" };",
|
||
" ",
|
||
" result.SyntaxError.prototype = Error.prototype;",
|
||
" ",
|
||
" return result;",
|
||
"})()",
|
||
{
|
||
initializerCode: initializerCode,
|
||
parseFunctionTableItems: parseFunctionTableItems.join(",\n"),
|
||
parseFunctionDefinitions: parseFunctionDefinitions.join("\n\n"),
|
||
startRule: node.startRule
|
||
}
|
||
);
|
||
},
|
||
|
||
initializer: function(node) {
|
||
return node.code;
|
||
},
|
||
|
||
rule: function(node) {
|
||
/*
|
||
* We want to reset variable names at the beginning of every function so
|
||
* that a little change in the source grammar does not change variables in
|
||
* all the generated code. This is desired especially when one has the
|
||
* generated grammar stored in a VCS (this is true e.g. for our
|
||
* metagrammar).
|
||
*/
|
||
UID.reset();
|
||
|
||
var resultVar = UID.next("result");
|
||
|
||
if (node.displayName !== null) {
|
||
var setReportMatchFailuresCode = formatCode(
|
||
"var savedReportMatchFailures = reportMatchFailures;",
|
||
"reportMatchFailures = false;"
|
||
);
|
||
var restoreReportMatchFailuresCode = formatCode(
|
||
"reportMatchFailures = savedReportMatchFailures;"
|
||
);
|
||
var reportMatchFailureCode = formatCode(
|
||
"if (reportMatchFailures && ${resultVar} === null) {",
|
||
" matchFailed(${displayName|string});",
|
||
"}",
|
||
{
|
||
displayName: node.displayName,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
} else {
|
||
var setReportMatchFailuresCode = "";
|
||
var restoreReportMatchFailuresCode = "";
|
||
var reportMatchFailureCode = "";
|
||
}
|
||
|
||
return formatCode(
|
||
"function parse_${name}() {",
|
||
" var cacheKey = '${name}@' + pos;",
|
||
" var cachedResult = cache[cacheKey];",
|
||
" if (cachedResult) {",
|
||
" pos = cachedResult.nextPos;",
|
||
" return cachedResult.result;",
|
||
" }",
|
||
" ",
|
||
" ${setReportMatchFailuresCode}",
|
||
" ${code}",
|
||
" ${restoreReportMatchFailuresCode}",
|
||
" ${reportMatchFailureCode}",
|
||
" ",
|
||
" cache[cacheKey] = {",
|
||
" nextPos: pos,",
|
||
" result: ${resultVar}",
|
||
" };",
|
||
" return ${resultVar};",
|
||
"}",
|
||
{
|
||
name: node.name,
|
||
setReportMatchFailuresCode: setReportMatchFailuresCode,
|
||
restoreReportMatchFailuresCode: restoreReportMatchFailuresCode,
|
||
reportMatchFailureCode: reportMatchFailureCode,
|
||
code: emit(node.expression, resultVar),
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
/*
|
||
* The contract for all code fragments generated by the following functions
|
||
* is as follows:
|
||
*
|
||
* * The code fragment should try to match a part of the input starting with
|
||
* the position indicated in |pos|. That position may point past the end of
|
||
* the input.
|
||
*
|
||
* * If the code fragment matches the input, it advances |pos| after the
|
||
* matched part of the input and sets variable with a name stored in
|
||
* |resultVar| to appropriate value, which is always non-null.
|
||
*
|
||
* * If the code fragment does not match the input, it does not change |pos|
|
||
* and it sets a variable with a name stored in |resultVar| to |null|.
|
||
*/
|
||
|
||
choice: function(node, resultVar) {
|
||
var code = formatCode(
|
||
"var ${resultVar} = null;",
|
||
{ resultVar: resultVar }
|
||
);
|
||
|
||
for (var i = node.alternatives.length - 1; i >= 0; i--) {
|
||
var alternativeResultVar = UID.next("result");
|
||
code = formatCode(
|
||
"${alternativeCode}",
|
||
"if (${alternativeResultVar} !== null) {",
|
||
" var ${resultVar} = ${alternativeResultVar};",
|
||
"} else {",
|
||
" ${code};",
|
||
"}",
|
||
{
|
||
alternativeCode: emit(node.alternatives[i], alternativeResultVar),
|
||
alternativeResultVar: alternativeResultVar,
|
||
code: code,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
}
|
||
|
||
return code;
|
||
},
|
||
|
||
sequence: function(node, resultVar) {
|
||
var savedPosVar = UID.next("savedPos");
|
||
|
||
var elementResultVars = map(node.elements, function() {
|
||
return UID.next("result")
|
||
});
|
||
|
||
var code = formatCode(
|
||
"var ${resultVar} = ${elementResultVarArray};",
|
||
{
|
||
resultVar: resultVar,
|
||
elementResultVarArray: "[" + elementResultVars.join(", ") + "]"
|
||
}
|
||
);
|
||
|
||
for (var i = node.elements.length - 1; i >= 0; i--) {
|
||
code = formatCode(
|
||
"${elementCode}",
|
||
"if (${elementResultVar} !== null) {",
|
||
" ${code}",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
" pos = ${savedPosVar};",
|
||
"}",
|
||
{
|
||
elementCode: emit(node.elements[i], elementResultVars[i]),
|
||
elementResultVar: elementResultVars[i],
|
||
code: code,
|
||
savedPosVar: savedPosVar,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
}
|
||
|
||
return formatCode(
|
||
"var ${savedPosVar} = pos;",
|
||
"${code}",
|
||
{
|
||
code: code,
|
||
savedPosVar: savedPosVar
|
||
}
|
||
);
|
||
},
|
||
|
||
labeled: function(node, resultVar) {
|
||
return emit(node.expression, resultVar);
|
||
},
|
||
|
||
simple_and: function(node, resultVar) {
|
||
var savedPosVar = UID.next("savedPos");
|
||
var savedReportMatchFailuresVar = UID.next("savedReportMatchFailuresVar");
|
||
var expressionResultVar = UID.next("result");
|
||
|
||
return formatCode(
|
||
"var ${savedPosVar} = pos;",
|
||
"var ${savedReportMatchFailuresVar} = reportMatchFailures;",
|
||
"reportMatchFailures = false;",
|
||
"${expressionCode}",
|
||
"reportMatchFailures = ${savedReportMatchFailuresVar};",
|
||
"if (${expressionResultVar} !== null) {",
|
||
" var ${resultVar} = '';",
|
||
" pos = ${savedPosVar};",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
"}",
|
||
{
|
||
expressionCode: emit(node.expression, expressionResultVar),
|
||
expressionResultVar: expressionResultVar,
|
||
savedPosVar: savedPosVar,
|
||
savedReportMatchFailuresVar: savedReportMatchFailuresVar,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
simple_not: function(node, resultVar) {
|
||
var savedPosVar = UID.next("savedPos");
|
||
var savedReportMatchFailuresVar = UID.next("savedReportMatchFailuresVar");
|
||
var expressionResultVar = UID.next("result");
|
||
|
||
return formatCode(
|
||
"var ${savedPosVar} = pos;",
|
||
"var ${savedReportMatchFailuresVar} = reportMatchFailures;",
|
||
"reportMatchFailures = false;",
|
||
"${expressionCode}",
|
||
"reportMatchFailures = ${savedReportMatchFailuresVar};",
|
||
"if (${expressionResultVar} === null) {",
|
||
" var ${resultVar} = '';",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
" pos = ${savedPosVar};",
|
||
"}",
|
||
{
|
||
expressionCode: emit(node.expression, expressionResultVar),
|
||
expressionResultVar: expressionResultVar,
|
||
savedPosVar: savedPosVar,
|
||
savedReportMatchFailuresVar: savedReportMatchFailuresVar,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
semantic_and: function(node, resultVar) {
|
||
return formatCode(
|
||
"var ${resultVar} = (function() {${actionCode}})() ? '' : null;",
|
||
{
|
||
actionCode: node.code,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
semantic_not: function(node, resultVar) {
|
||
return formatCode(
|
||
"var ${resultVar} = (function() {${actionCode}})() ? null : '';",
|
||
{
|
||
actionCode: node.code,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
optional: function(node, resultVar) {
|
||
var expressionResultVar = UID.next("result");
|
||
|
||
return formatCode(
|
||
"${expressionCode}",
|
||
"var ${resultVar} = ${expressionResultVar} !== null ? ${expressionResultVar} : '';",
|
||
{
|
||
expressionCode: emit(node.expression, expressionResultVar),
|
||
expressionResultVar: expressionResultVar,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
zero_or_more: function(node, resultVar) {
|
||
var expressionResultVar = UID.next("result");
|
||
|
||
return formatCode(
|
||
"var ${resultVar} = [];",
|
||
"${expressionCode}",
|
||
"while (${expressionResultVar} !== null) {",
|
||
" ${resultVar}.push(${expressionResultVar});",
|
||
" ${expressionCode}",
|
||
"}",
|
||
{
|
||
expressionCode: emit(node.expression, expressionResultVar),
|
||
expressionResultVar: expressionResultVar,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
one_or_more: function(node, resultVar) {
|
||
var expressionResultVar = UID.next("result");
|
||
|
||
return formatCode(
|
||
"${expressionCode}",
|
||
"if (${expressionResultVar} !== null) {",
|
||
" var ${resultVar} = [];",
|
||
" while (${expressionResultVar} !== null) {",
|
||
" ${resultVar}.push(${expressionResultVar});",
|
||
" ${expressionCode}",
|
||
" }",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
"}",
|
||
{
|
||
expressionCode: emit(node.expression, expressionResultVar),
|
||
expressionResultVar: expressionResultVar,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
action: function(node, resultVar) {
|
||
/*
|
||
* In case of sequences, we splat their elements into function arguments
|
||
* one by one. Example:
|
||
*
|
||
* start: a:"a" b:"b" c:"c" { alert(arguments.length) } // => 3
|
||
*
|
||
* This behavior is reflected in this function.
|
||
*/
|
||
|
||
var expressionResultVar = UID.next("result");
|
||
|
||
if (node.expression.type === "sequence") {
|
||
var formalParams = [];
|
||
var actualParams = [];
|
||
|
||
var elements = node.expression.elements;
|
||
var elementsLength = elements.length;
|
||
for (var i = 0; i < elementsLength; i++) {
|
||
if (elements[i].type === "labeled") {
|
||
formalParams.push(elements[i].label);
|
||
actualParams.push(expressionResultVar + "[" + i + "]");
|
||
}
|
||
}
|
||
} else if (node.expression.type === "labeled") {
|
||
var formalParams = [node.expression.label];
|
||
var actualParams = [expressionResultVar];
|
||
} else {
|
||
var formalParams = [];
|
||
var actualParams = [];
|
||
}
|
||
|
||
return formatCode(
|
||
"${expressionCode}",
|
||
"var ${resultVar} = ${expressionResultVar} !== null",
|
||
" ? (function(${formalParams}) {${actionCode}})(${actualParams})",
|
||
" : null;",
|
||
{
|
||
expressionCode: emit(node.expression, expressionResultVar),
|
||
expressionResultVar: expressionResultVar,
|
||
actionCode: node.code,
|
||
formalParams: formalParams.join(", "),
|
||
actualParams: actualParams.join(", "),
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
rule_ref: function(node, resultVar) {
|
||
return formatCode(
|
||
"var ${resultVar} = ${ruleMethod}();",
|
||
{
|
||
ruleMethod: "parse_" + node.name,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
literal: function(node, resultVar) {
|
||
return formatCode(
|
||
"if (input.substr(pos, ${length}) === ${value|string}) {",
|
||
" var ${resultVar} = ${value|string};",
|
||
" pos += ${length};",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
" if (reportMatchFailures) {",
|
||
" matchFailed(${valueQuoted|string});",
|
||
" }",
|
||
"}",
|
||
{
|
||
value: node.value,
|
||
valueQuoted: quote(node.value),
|
||
length: node.value.length,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
},
|
||
|
||
any: function(node, resultVar) {
|
||
return formatCode(
|
||
"if (input.length > pos) {",
|
||
" var ${resultVar} = input.charAt(pos);",
|
||
" pos++;",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
" if (reportMatchFailures) {",
|
||
" matchFailed('any character');",
|
||
" }",
|
||
"}",
|
||
{ resultVar: resultVar }
|
||
);
|
||
},
|
||
|
||
"class": function(node, resultVar) {
|
||
if (node.parts.length > 0) {
|
||
var regexp = "/^["
|
||
+ (node.inverted ? "^" : "")
|
||
+ map(node.parts, function(part) {
|
||
return part instanceof Array
|
||
? quoteForRegexpClass(part[0])
|
||
+ "-"
|
||
+ quoteForRegexpClass(part[1])
|
||
: quoteForRegexpClass(part);
|
||
}).join("")
|
||
+ "]/";
|
||
} else {
|
||
/*
|
||
* Stupid IE considers regexps /[]/ and /[^]/ syntactically invalid, so
|
||
* we translate them into euqivalents it can handle.
|
||
*/
|
||
var regexp = node.inverted ? "/^[\\S\\s]/" : "/^(?!)/";
|
||
}
|
||
|
||
return formatCode(
|
||
"if (input.substr(pos).match(${regexp}) !== null) {",
|
||
" var ${resultVar} = input.charAt(pos);",
|
||
" pos++;",
|
||
"} else {",
|
||
" var ${resultVar} = null;",
|
||
" if (reportMatchFailures) {",
|
||
" matchFailed(${rawText|string});",
|
||
" }",
|
||
"}",
|
||
{
|
||
regexp: regexp,
|
||
rawText: node.rawText,
|
||
resultVar: resultVar
|
||
}
|
||
);
|
||
}
|
||
});
|
||
|
||
return emit(ast);
|
||
};
|
||
|
||
if (typeof module === "object") {
|
||
module.exports = PEG;
|
||
} else if (typeof window === "object") {
|
||
window.PEG = PEG;
|
||
} else {
|
||
throw new Error("Can't export PEG library (no \"module\" nor \"window\" object detected).");
|
||
}
|
||
|
||
})();
|