From 3a3f4e2ce6e1a1ca1f90214a641f94643c27468e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 12 Mar 2013 17:41:18 -0700 Subject: [PATCH] Use pegjs node module --- package.json | 3 +- vendor/pegjs.js | 4528 ----------------------------------------------- 2 files changed, 2 insertions(+), 4529 deletions(-) delete mode 100644 vendor/pegjs.js diff --git a/package.json b/package.json index e721f124d..5274f8000 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "git-utils": "0.3.0", "underscore": "1.4.4", "d3": "3.0.8", - "coffee-cache": "0.1.0" + "coffee-cache": "0.1.0", + "pegjs": "0.7.0" }, "scripts": { diff --git a/vendor/pegjs.js b/vendor/pegjs.js deleted file mode 100644 index 42e67b359..000000000 --- a/vendor/pegjs.js +++ /dev/null @@ -1,4528 +0,0 @@ -/* - * PEG.js 0.7.0 - * - * http://pegjs.majda.cz/ - * - * Copyright (c) 2010-2012 David Majda - * Licensend under the MIT license. - */ -var PEG = (function(undefined) { - -var PEG = { - /* PEG.js version (uses semantic versioning). */ - VERSION: "0.7.0", - - /* - * 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, options) { - return PEG.compiler.compile(PEG.parser.parse(grammar), options); - } -}; - -/* Thrown when the grammar contains an error. */ - -PEG.GrammarError = function(message) { - this.name = "PEG.GrammarError"; - this.message = message; -}; - -PEG.GrammarError.prototype = Error.prototype; - -/* Like Python's |range|, but without |step|. */ -function range(start, stop) { - if (stop === undefined) { - stop = start; - start = 0; - } - - var result = new Array(Math.max(0, stop - start)); - for (var i = 0, j = start; j < stop; i++, j++) { - result[i] = j; - } - return result; -} - -function find(array, callback) { - var length = array.length; - for (var i = 0; i < length; i++) { - if (callback(array[i])) { - return array[i]; - } - } -} - -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], i); - } -} - -function map(array, callback) { - var result = []; - var length = array.length; - for (var i = 0; i < length; i++) { - result[i] = callback(array[i], i); - } - return result; -} - -function pluck(array, key) { - return map(array, function (e) { return e[key]; }); -} - -function keys(object) { - var result = []; - for (var key in object) { - result.push(key); - } - return result; -} - -function values(object) { - var result = []; - for (var key in object) { - result.push(object[key]); - } - return result; -} - -/* - * Returns a string padded on the left to a desired length with a character. - * - * The code needs to be in sync with the 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 the code template in the compilation - * function for "action" nodes. - */ -function escape(ch) { - var charCode = ch.charCodeAt(0); - var escapeChar; - var length; - - if (charCode <= 0xFF) { - escapeChar = 'x'; - length = 2; - } else { - escapeChar = 'u'; - 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 the 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 control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used because - * JSHint does not like the first and IE the second. - */ - return '"' + s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing quote character - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) - + '"'; -} - -/* - * 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 control and non-ASCII - * characters. - */ - return s - .replace(/\\/g, '\\\\') // backslash - .replace(/\//g, '\\/') // closing slash - .replace(/\]/g, '\\]') // closing bracket - .replace(/-/g, '\\-') // dash - .replace(/\0/g, '\\0') // null - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\v/g, '\\x0B') // vertical tab - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x01-\x08\x0E-\x1F\x80-\uFFFF]/g, escape); -} - -/* - * 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); - }; -} - -function findRuleByName(ast, name) { - return find(ast.rules, function(r) { return r.name === name; }); -} -PEG.parser = (function(){ - /* - * Generated by PEG.js 0.7.0. - * - * http://pegjs.majda.cz/ - */ - - 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 control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used - * because JSHint does not like the first and IE the second. - */ - return '"' + s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing quote character - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) - + '"'; - } - - 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 = { - "grammar": parse_grammar, - "initializer": parse_initializer, - "rule": parse_rule, - "choice": parse_choice, - "sequence": parse_sequence, - "labeled": parse_labeled, - "prefixed": parse_prefixed, - "suffixed": parse_suffixed, - "primary": parse_primary, - "action": parse_action, - "braced": parse_braced, - "nonBraceCharacters": parse_nonBraceCharacters, - "nonBraceCharacter": parse_nonBraceCharacter, - "equals": parse_equals, - "colon": parse_colon, - "semicolon": parse_semicolon, - "slash": parse_slash, - "and": parse_and, - "not": parse_not, - "question": parse_question, - "star": parse_star, - "plus": parse_plus, - "lparen": parse_lparen, - "rparen": parse_rparen, - "dot": parse_dot, - "identifier": parse_identifier, - "literal": parse_literal, - "string": parse_string, - "doubleQuotedString": parse_doubleQuotedString, - "doubleQuotedCharacter": parse_doubleQuotedCharacter, - "simpleDoubleQuotedCharacter": parse_simpleDoubleQuotedCharacter, - "singleQuotedString": parse_singleQuotedString, - "singleQuotedCharacter": parse_singleQuotedCharacter, - "simpleSingleQuotedCharacter": parse_simpleSingleQuotedCharacter, - "class": parse_class, - "classCharacterRange": parse_classCharacterRange, - "classCharacter": parse_classCharacter, - "bracketDelimitedCharacter": parse_bracketDelimitedCharacter, - "simpleBracketDelimitedCharacter": parse_simpleBracketDelimitedCharacter, - "simpleEscapeSequence": parse_simpleEscapeSequence, - "zeroEscapeSequence": parse_zeroEscapeSequence, - "hexEscapeSequence": parse_hexEscapeSequence, - "unicodeEscapeSequence": parse_unicodeEscapeSequence, - "eolEscapeSequence": parse_eolEscapeSequence, - "digit": parse_digit, - "hexDigit": parse_hexDigit, - "letter": parse_letter, - "lowerCaseLetter": parse_lowerCaseLetter, - "upperCaseLetter": parse_upperCaseLetter, - "__": parse___, - "comment": parse_comment, - "singleLineComment": parse_singleLineComment, - "multiLineComment": parse_multiLineComment, - "eol": parse_eol, - "eolChar": parse_eolChar, - "whitespace": parse_whitespace - }; - - if (startRule !== undefined) { - if (parseFunctions[startRule] === undefined) { - throw new Error("Invalid rule name: " + quote(startRule) + "."); - } - } else { - startRule = "grammar"; - } - - var pos = 0; - var reportFailures = 0; - var rightmostFailuresPos = 0; - var rightmostFailuresExpected = []; - - 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); - var escapeChar; - var length; - - if (charCode <= 0xFF) { - escapeChar = 'x'; - length = 2; - } else { - escapeChar = 'u'; - length = 4; - } - - return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); - } - - function matchFailed(failure) { - if (pos < rightmostFailuresPos) { - return; - } - - if (pos > rightmostFailuresPos) { - rightmostFailuresPos = pos; - rightmostFailuresExpected = []; - } - - rightmostFailuresExpected.push(failure); - } - - function parse_grammar() { - var result0, result1, result2, result3; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse___(); - if (result0 !== null) { - result1 = parse_initializer(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result3 = parse_rule(); - if (result3 !== null) { - result2 = []; - while (result3 !== null) { - result2.push(result3); - result3 = parse_rule(); - } - } else { - result2 = null; - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, initializer, rules) { - return { - type: "grammar", - initializer: initializer !== "" ? initializer : null, - rules: rules, - startRule: rules[0].name - }; - })(pos0, result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_initializer() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_action(); - if (result0 !== null) { - result1 = parse_semicolon(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, code) { - return { - type: "initializer", - code: code - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_rule() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_identifier(); - if (result0 !== null) { - result1 = parse_string(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = parse_equals(); - if (result2 !== null) { - result3 = parse_choice(); - if (result3 !== null) { - result4 = parse_semicolon(); - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, displayName, expression) { - return { - type: "rule", - name: name, - displayName: displayName !== "" ? displayName : null, - expression: expression - }; - })(pos0, result0[0], result0[1], result0[3]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_choice() { - var result0, result1, result2, result3; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_sequence(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse_slash(); - if (result2 !== null) { - result3 = parse_sequence(); - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse_slash(); - if (result2 !== null) { - result3 = parse_sequence(); - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, 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; - } - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_sequence() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = []; - result1 = parse_labeled(); - while (result1 !== null) { - result0.push(result1); - result1 = parse_labeled(); - } - if (result0 !== null) { - result1 = parse_action(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, elements, code) { - var expression = elements.length !== 1 - ? { - type: "sequence", - elements: elements - } - : elements[0]; - return { - type: "action", - expression: expression, - code: code - }; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = []; - result1 = parse_labeled(); - while (result1 !== null) { - result0.push(result1); - result1 = parse_labeled(); - } - if (result0 !== null) { - result0 = (function(offset, elements) { - return elements.length !== 1 - ? { - type: "sequence", - elements: elements - } - : elements[0]; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_labeled() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_identifier(); - if (result0 !== null) { - result1 = parse_colon(); - if (result1 !== null) { - result2 = parse_prefixed(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, label, expression) { - return { - type: "labeled", - label: label, - expression: expression - }; - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_prefixed(); - } - return result0; - } - - function parse_prefixed() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_and(); - if (result0 !== null) { - result1 = parse_action(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, code) { - return { - type: "semantic_and", - code: code - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_and(); - if (result0 !== null) { - result1 = parse_suffixed(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "simple_and", - expression: expression - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_not(); - if (result0 !== null) { - result1 = parse_action(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, code) { - return { - type: "semantic_not", - code: code - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_not(); - if (result0 !== null) { - result1 = parse_suffixed(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "simple_not", - expression: expression - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_suffixed(); - } - } - } - } - return result0; - } - - function parse_suffixed() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = parse_question(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "optional", - expression: expression - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = parse_star(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "zero_or_more", - expression: expression - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = parse_plus(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "one_or_more", - expression: expression - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_primary(); - } - } - } - return result0; - } - - function parse_primary() { - var result0, result1, result2; - var pos0, pos1, pos2, pos3; - - pos0 = pos; - pos1 = pos; - result0 = parse_identifier(); - if (result0 !== null) { - pos2 = pos; - reportFailures++; - pos3 = pos; - result1 = parse_string(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = parse_equals(); - if (result2 !== null) { - result1 = [result1, result2]; - } else { - result1 = null; - pos = pos3; - } - } else { - result1 = null; - pos = pos3; - } - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name) { - return { - type: "rule_ref", - name: name - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_literal(); - if (result0 === null) { - pos0 = pos; - result0 = parse_dot(); - if (result0 !== null) { - result0 = (function(offset) { return { type: "any" }; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_class(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_lparen(); - if (result0 !== null) { - result1 = parse_choice(); - if (result1 !== null) { - result2 = parse_rparen(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { return expression; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - } - } - } - } - return result0; - } - - function parse_action() { - var result0, result1; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_braced(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, braced) { return braced.substr(1, braced.length - 2); })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("action"); - } - return result0; - } - - function parse_braced() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 123) { - result0 = "{"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"{\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_braced(); - if (result2 === null) { - result2 = parse_nonBraceCharacter(); - } - while (result2 !== null) { - result1.push(result2); - result2 = parse_braced(); - if (result2 === null) { - result2 = parse_nonBraceCharacter(); - } - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 125) { - result2 = "}"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"}\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, parts) { - return "{" + parts.join("") + "}"; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_nonBraceCharacters() { - var result0, result1; - var pos0; - - pos0 = pos; - result1 = parse_nonBraceCharacter(); - if (result1 !== null) { - result0 = []; - while (result1 !== null) { - result0.push(result1); - result1 = parse_nonBraceCharacter(); - } - } else { - result0 = null; - } - if (result0 !== null) { - result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_nonBraceCharacter() { - var result0; - - if (/^[^{}]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[^{}]"); - } - } - return result0; - } - - function parse_equals() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 61) { - result0 = "="; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "="; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_colon() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 58) { - result0 = ":"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\":\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return ":"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_semicolon() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 59) { - result0 = ";"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\";\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return ";"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_slash() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 47) { - result0 = "/"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"/\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "/"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_and() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 38) { - result0 = "&"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"&\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "&"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_not() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 33) { - result0 = "!"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"!\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "!"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_question() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 63) { - result0 = "?"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"?\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "?"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_star() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 42) { - result0 = "*"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"*\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "*"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_plus() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 43) { - result0 = "+"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"+\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "+"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_lparen() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 40) { - result0 = "("; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"(\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "("; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_rparen() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 41) { - result0 = ")"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\")\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return ")"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_dot() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 46) { - result0 = "."; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\".\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "."; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_identifier() { - var result0, result1, result2; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_letter(); - if (result0 === null) { - if (input.charCodeAt(pos) === 95) { - result0 = "_"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"_\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 36) { - result0 = "$"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_letter(); - if (result2 === null) { - result2 = parse_digit(); - if (result2 === null) { - if (input.charCodeAt(pos) === 95) { - result2 = "_"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"_\""); - } - } - if (result2 === null) { - if (input.charCodeAt(pos) === 36) { - result2 = "$"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - } - } - } - while (result2 !== null) { - result1.push(result2); - result2 = parse_letter(); - if (result2 === null) { - result2 = parse_digit(); - if (result2 === null) { - if (input.charCodeAt(pos) === 95) { - result2 = "_"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"_\""); - } - } - if (result2 === null) { - if (input.charCodeAt(pos) === 36) { - result2 = "$"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - } - } - } - } - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return head + tail.join(""); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("identifier"); - } - return result0; - } - - function parse_literal() { - var result0, result1, result2; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_doubleQuotedString(); - if (result0 === null) { - result0 = parse_singleQuotedString(); - } - if (result0 !== null) { - if (input.charCodeAt(pos) === 105) { - result1 = "i"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"i\""); - } - } - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, value, flags) { - return { - type: "literal", - value: value, - ignoreCase: flags === "i" - }; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("literal"); - } - return result0; - } - - function parse_string() { - var result0, result1; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_doubleQuotedString(); - if (result0 === null) { - result0 = parse_singleQuotedString(); - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, string) { return string; })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("string"); - } - return result0; - } - - function parse_doubleQuotedString() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 34) { - result0 = "\""; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_doubleQuotedCharacter(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_doubleQuotedCharacter(); - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 34) { - result2 = "\""; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_doubleQuotedCharacter() { - var result0; - - result0 = parse_simpleDoubleQuotedCharacter(); - if (result0 === null) { - result0 = parse_simpleEscapeSequence(); - if (result0 === null) { - result0 = parse_zeroEscapeSequence(); - if (result0 === null) { - result0 = parse_hexEscapeSequence(); - if (result0 === null) { - result0 = parse_unicodeEscapeSequence(); - if (result0 === null) { - result0 = parse_eolEscapeSequence(); - } - } - } - } - } - return result0; - } - - function parse_simpleDoubleQuotedCharacter() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 34) { - result0 = "\""; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 === null) { - result0 = parse_eolChar(); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos2; - } - if (result0 !== null) { - if (input.length > pos) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { return char_; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_singleQuotedString() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 39) { - result0 = "'"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_singleQuotedCharacter(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_singleQuotedCharacter(); - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 39) { - result2 = "'"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_singleQuotedCharacter() { - var result0; - - result0 = parse_simpleSingleQuotedCharacter(); - if (result0 === null) { - result0 = parse_simpleEscapeSequence(); - if (result0 === null) { - result0 = parse_zeroEscapeSequence(); - if (result0 === null) { - result0 = parse_hexEscapeSequence(); - if (result0 === null) { - result0 = parse_unicodeEscapeSequence(); - if (result0 === null) { - result0 = parse_eolEscapeSequence(); - } - } - } - } - } - return result0; - } - - function parse_simpleSingleQuotedCharacter() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 39) { - result0 = "'"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 === null) { - result0 = parse_eolChar(); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos2; - } - if (result0 !== null) { - if (input.length > pos) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { return char_; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_class() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 91) { - result0 = "["; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"[\""); - } - } - if (result0 !== null) { - if (input.charCodeAt(pos) === 94) { - result1 = "^"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"^\""); - } - } - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = []; - result3 = parse_classCharacterRange(); - if (result3 === null) { - result3 = parse_classCharacter(); - } - while (result3 !== null) { - result2.push(result3); - result3 = parse_classCharacterRange(); - if (result3 === null) { - result3 = parse_classCharacter(); - } - } - if (result2 !== null) { - if (input.charCodeAt(pos) === 93) { - result3 = "]"; - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("\"]\""); - } - } - if (result3 !== null) { - if (input.charCodeAt(pos) === 105) { - result4 = "i"; - pos++; - } else { - result4 = null; - if (reportFailures === 0) { - matchFailed("\"i\""); - } - } - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result0 = [result0, result1, result2, result3, result4, result5]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, inverted, parts, flags) { - var partsConverted = map(parts, function(part) { return part.data; }); - var rawText = "[" - + inverted - + map(parts, function(part) { return part.rawText; }).join("") - + "]" - + flags; - - return { - type: "class", - inverted: inverted === "^", - ignoreCase: flags === "i", - parts: partsConverted, - // FIXME: Get the raw text from the input directly. - rawText: rawText - }; - })(pos0, result0[1], result0[2], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("character class"); - } - return result0; - } - - function parse_classCharacterRange() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_classCharacter(); - if (result0 !== null) { - if (input.charCodeAt(pos) === 45) { - result1 = "-"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"-\""); - } - } - if (result1 !== null) { - result2 = parse_classCharacter(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, 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 - }; - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_classCharacter() { - var result0; - var pos0; - - pos0 = pos; - result0 = parse_bracketDelimitedCharacter(); - if (result0 !== null) { - result0 = (function(offset, char_) { - return { - data: char_, - // FIXME: Get the raw text from the input directly. - rawText: quoteForRegexpClass(char_) - }; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_bracketDelimitedCharacter() { - var result0; - - result0 = parse_simpleBracketDelimitedCharacter(); - if (result0 === null) { - result0 = parse_simpleEscapeSequence(); - if (result0 === null) { - result0 = parse_zeroEscapeSequence(); - if (result0 === null) { - result0 = parse_hexEscapeSequence(); - if (result0 === null) { - result0 = parse_unicodeEscapeSequence(); - if (result0 === null) { - result0 = parse_eolEscapeSequence(); - } - } - } - } - } - return result0; - } - - function parse_simpleBracketDelimitedCharacter() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 93) { - result0 = "]"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"]\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 === null) { - result0 = parse_eolChar(); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos2; - } - if (result0 !== null) { - if (input.length > pos) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { return char_; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_simpleEscapeSequence() { - var result0, result1, result2; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_digit(); - if (result1 === null) { - if (input.charCodeAt(pos) === 120) { - result1 = "x"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"x\""); - } - } - if (result1 === null) { - if (input.charCodeAt(pos) === 117) { - result1 = "u"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"u\""); - } - } - if (result1 === null) { - result1 = parse_eolChar(); - } - } - } - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - if (input.length > pos) { - result2 = input.charAt(pos); - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, 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". - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_zeroEscapeSequence() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\0") { - result0 = "\\0"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\0\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_digit(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "\x00"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_hexEscapeSequence() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\x") { - result0 = "\\x"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\x\""); - } - } - if (result0 !== null) { - result1 = parse_hexDigit(); - if (result1 !== null) { - result2 = parse_hexDigit(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, h1, h2) { - return String.fromCharCode(parseInt(h1 + h2, 16)); - })(pos0, result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_unicodeEscapeSequence() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\u") { - result0 = "\\u"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\u\""); - } - } - if (result0 !== null) { - result1 = parse_hexDigit(); - if (result1 !== null) { - result2 = parse_hexDigit(); - if (result2 !== null) { - result3 = parse_hexDigit(); - if (result3 !== null) { - result4 = parse_hexDigit(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, h1, h2, h3, h4) { - return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16)); - })(pos0, result0[1], result0[2], result0[3], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_eolEscapeSequence() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 !== null) { - result1 = parse_eol(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, eol) { return eol; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_digit() { - var result0; - - if (/^[0-9]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[0-9]"); - } - } - return result0; - } - - function parse_hexDigit() { - var result0; - - if (/^[0-9a-fA-F]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[0-9a-fA-F]"); - } - } - return result0; - } - - function parse_letter() { - var result0; - - result0 = parse_lowerCaseLetter(); - if (result0 === null) { - result0 = parse_upperCaseLetter(); - } - return result0; - } - - function parse_lowerCaseLetter() { - var result0; - - if (/^[a-z]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[a-z]"); - } - } - return result0; - } - - function parse_upperCaseLetter() { - var result0; - - if (/^[A-Z]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[A-Z]"); - } - } - return result0; - } - - function parse___() { - var result0, result1; - - result0 = []; - result1 = parse_whitespace(); - if (result1 === null) { - result1 = parse_eol(); - if (result1 === null) { - result1 = parse_comment(); - } - } - while (result1 !== null) { - result0.push(result1); - result1 = parse_whitespace(); - if (result1 === null) { - result1 = parse_eol(); - if (result1 === null) { - result1 = parse_comment(); - } - } - } - return result0; - } - - function parse_comment() { - var result0; - - reportFailures++; - result0 = parse_singleLineComment(); - if (result0 === null) { - result0 = parse_multiLineComment(); - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("comment"); - } - return result0; - } - - function parse_singleLineComment() { - var result0, result1, result2, result3; - var pos0, pos1, pos2; - - pos0 = pos; - if (input.substr(pos, 2) === "//") { - result0 = "//"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"//\""); - } - } - if (result0 !== null) { - result1 = []; - pos1 = pos; - pos2 = pos; - reportFailures++; - result2 = parse_eolChar(); - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - while (result2 !== null) { - result1.push(result2); - pos1 = pos; - pos2 = pos; - reportFailures++; - result2 = parse_eolChar(); - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_multiLineComment() { - var result0, result1, result2, result3; - var pos0, pos1, pos2; - - pos0 = pos; - if (input.substr(pos, 2) === "/*") { - result0 = "/*"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"/*\""); - } - } - if (result0 !== null) { - result1 = []; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.substr(pos, 2) === "*/") { - result2 = "*/"; - pos += 2; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"*/\""); - } - } - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - while (result2 !== null) { - result1.push(result2); - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.substr(pos, 2) === "*/") { - result2 = "*/"; - pos += 2; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"*/\""); - } - } - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - } - if (result1 !== null) { - if (input.substr(pos, 2) === "*/") { - result2 = "*/"; - pos += 2; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"*/\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_eol() { - var result0; - - reportFailures++; - if (input.charCodeAt(pos) === 10) { - result0 = "\n"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\n\""); - } - } - if (result0 === null) { - if (input.substr(pos, 2) === "\r\n") { - result0 = "\r\n"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\r\\n\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 13) { - result0 = "\r"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\r\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 8232) { - result0 = "\u2028"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\u2028\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 8233) { - result0 = "\u2029"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\u2029\""); - } - } - } - } - } - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("end of line"); - } - return result0; - } - - function parse_eolChar() { - var result0; - - if (/^[\n\r\u2028\u2029]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[\\n\\r\\u2028\\u2029]"); - } - } - return result0; - } - - function parse_whitespace() { - var result0; - - reportFailures++; - if (/^[ \t\x0B\f\xA0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[ \\t\\x0B\\f\\xA0\\uFEFF\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]"); - } - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("whitespace"); - } - return result0; - } - - - function cleanupExpected(expected) { - expected.sort(); - - var lastExpected = null; - var cleanExpected = []; - for (var i = 0; i < expected.length; i++) { - if (expected[i] !== lastExpected) { - cleanExpected.push(expected[i]); - lastExpected = expected[i]; - } - } - return cleanExpected; - } - - function computeErrorPosition() { - /* - * The first idea was to use |String.split| to break the input up to the - * error position along newlines and derive the line and column from - * there. However IE's |split| implementation is so broken that it was - * enough to prevent it. - */ - - var line = 1; - var column = 1; - var seenCR = false; - - for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) { - var ch = input.charAt(i); - if (ch === "\n") { - if (!seenCR) { line++; } - column = 1; - seenCR = false; - } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { - line++; - column = 1; - seenCR = true; - } else { - column++; - seenCR = false; - } - } - - 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| - * - |rightmostFailuresExpected| may or may not contain something - * - * 2. The parser successfully parsed only a part of the input. - * - * - |result !== null| - * - |pos < input.length| - * - |rightmostFailuresExpected| may or may not contain something - * - * 3. The parser did not successfully parse any part of the input. - * - * - |result === null| - * - |pos === 0| - * - |rightmostFailuresExpected| contains at least one failure - * - * All code following this comment (including called functions) must - * handle these states. - */ - if (result === null || pos !== input.length) { - var offset = Math.max(pos, rightmostFailuresPos); - var found = offset < input.length ? input.charAt(offset) : null; - var errorPosition = computeErrorPosition(); - - throw new this.SyntaxError( - cleanupExpected(rightmostFailuresExpected), - found, - offset, - 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(expected, found, offset, line, column) { - function buildMessage(expected, found) { - var expectedHumanized, foundHumanized; - - switch (expected.length) { - case 0: - expectedHumanized = "end of input"; - break; - case 1: - expectedHumanized = expected[0]; - break; - default: - expectedHumanized = expected.slice(0, expected.length - 1).join(", ") - + " or " - + expected[expected.length - 1]; - } - - foundHumanized = found ? quote(found) : "end of input"; - - return "Expected " + expectedHumanized + " but " + foundHumanized + " found."; - } - - this.name = "SyntaxError"; - this.expected = expected; - this.found = found; - this.message = buildMessage(expected, found); - this.offset = offset; - this.line = line; - this.column = column; - }; - - result.SyntaxError.prototype = Error.prototype; - - return result; -})(); -PEG.compiler = { - /* - * Names of passes that will get run during the compilation (in the specified - * order). - */ - appliedPassNames: [ - "reportMissingRules", - "reportLeftRecursion", - "removeProxyRules", - "computeVarNames", - "computeParams" - ], - - /* - * 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, options) { - var that = this; - - each(this.appliedPassNames, function(passName) { - that.passes[passName](ast); - }); - - var source = this.emitter(ast, options); - var result = eval(source); - result._source = source; - - return result; - } -}; - -/* - * Compiler passes. - * - * Each pass is a function that is passed the AST. It can perform checks on it - * or modify it as needed. If the pass encounters a semantic error, it throws - * |PEG.GrammarError|. - */ -PEG.compiler.passes = { - /* Checks that all referenced rules exist. */ - reportMissingRules: function(ast) { - function nop() {} - - function checkExpression(node) { check(node.expression); } - - function checkSubnodes(propertyName) { - return function(node) { each(node[propertyName], check); }; - } - - var check = buildNodeVisitor({ - grammar: checkSubnodes("rules"), - 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 (!findRuleByName(ast, node.name)) { - 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. */ - reportLeftRecursion: function(ast) { - function nop() {} - - function checkExpression(node, appliedRules) { - check(node.expression, appliedRules); - } - - function checkSubnodes(propertyName) { - return function(node, appliedRules) { - each(node[propertyName], function(subnode) { - check(subnode, appliedRules); - }); - }; - } - - var check = buildNodeVisitor({ - grammar: checkSubnodes("rules"), - - rule: - function(node, appliedRules) { - check(node.expression, appliedRules.concat(node.name)); - }, - - choice: checkSubnodes("alternatives"), - - 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(findRuleByName(ast, node.name), appliedRules); - }, - - literal: nop, - any: nop, - "class": nop - }); - - check(ast, []); - }, - - /* - * Removes proxy rules -- that is, rules that only delegate to other rule. - */ - removeProxyRules: 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: replaceInSubnodes("rules"), - 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); - } - - var indices = []; - - each(ast.rules, function(rule, i) { - if (isProxyRule(rule)) { - replaceRuleRefs(ast, rule.name, rule.expression.name); - if (rule.name === ast.startRule) { - ast.startRule = rule.expression.name; - } - indices.push(i); - } - }); - - indices.reverse(); - - each(indices, function(index) { - ast.rules.splice(index, 1); - }); - }, - - /* - * Computes names of variables used for storing match results and parse - * positions in generated code. These variables are organized as two stacks. - * The following will hold after running this pass: - * - * * All nodes except "grammar" and "rule" nodes will have a |resultVar| - * property. It will contain a name of the variable that will store a - * match result of the expression represented by the node in generated - * code. - * - * * Some nodes will have a |posVar| property. It will contain a name of the - * variable that will store a parse position in generated code. - * - * * All "rule" nodes will contain |resultVars| and |posVars| properties. - * They will contain a list of values of |resultVar| and |posVar| - * properties used in rule's subnodes. (This is useful to declare - * variables in generated code.) - */ - computeVarNames: function(ast) { - function resultVar(index) { return "result" + index; } - function posVar(index) { return "pos" + index; } - - function computeLeaf(node, index) { - node.resultVar = resultVar(index.result); - - return { result: 0, pos: 0 }; - } - - function computeFromExpression(delta) { - return function(node, index) { - var depth = compute( - node.expression, - { - result: index.result + delta.result, - pos: index.pos + delta.pos - } - ); - - node.resultVar = resultVar(index.result); - if (delta.pos !== 0) { - node.posVar = posVar(index.pos); - } - - return { - result: depth.result + delta.result, - pos: depth.pos + delta.pos - }; - }; - } - - var compute = buildNodeVisitor({ - grammar: - function(node, index) { - each(node.rules, function(node) { - compute(node, index); - }); - }, - - rule: - function(node, index) { - var depth = compute(node.expression, index); - - node.resultVar = resultVar(index.result); - node.resultVars = map(range(depth.result + 1), resultVar); - node.posVars = map(range(depth.pos), posVar); - }, - - choice: - function(node, index) { - var depths = map(node.alternatives, function(alternative) { - return compute(alternative, index); - }); - - node.resultVar = resultVar(index.result); - - return { - result: Math.max.apply(null, pluck(depths, "result")), - pos: Math.max.apply(null, pluck(depths, "pos")) - }; - }, - - sequence: - function(node, index) { - var depths = map(node.elements, function(element, i) { - return compute( - element, - { result: index.result + i, pos: index.pos + 1 } - ); - }); - - node.resultVar = resultVar(index.result); - node.posVar = posVar(index.pos); - - return { - result: - node.elements.length > 0 - ? Math.max.apply( - null, - map(depths, function(d, i) { return i + d.result; }) - ) - : 0, - - pos: - node.elements.length > 0 - ? 1 + Math.max.apply(null, pluck(depths, "pos")) - : 1 - }; - }, - - labeled: computeFromExpression({ result: 0, pos: 0 }), - simple_and: computeFromExpression({ result: 0, pos: 1 }), - simple_not: computeFromExpression({ result: 0, pos: 1 }), - semantic_and: computeLeaf, - semantic_not: computeLeaf, - optional: computeFromExpression({ result: 0, pos: 0 }), - zero_or_more: computeFromExpression({ result: 1, pos: 0 }), - one_or_more: computeFromExpression({ result: 1, pos: 0 }), - action: computeFromExpression({ result: 0, pos: 1 }), - rule_ref: computeLeaf, - literal: computeLeaf, - any: computeLeaf, - "class": computeLeaf - }); - - compute(ast, { result: 0, pos: 0 }); - }, - - /* - * This pass walks through the AST and tracks what labels are visible at each - * point. For "action", "semantic_and" and "semantic_or" nodes it computes - * parameter names and values for the function used in generated code. (In the - * emitter, user's code is wrapped into a function that is immediately - * executed. Its parameter names correspond to visible labels and its - * parameter values to their captured values). Implicitly, this pass defines - * scoping rules for labels. - * - * After running this pass, all "action", "semantic_and" and "semantic_or" - * nodes will have a |params| property containing an object mapping parameter - * names to the expressions that will be used as their values. - */ - computeParams: function(ast) { - var envs = []; - - function scoped(f) { - envs.push({}); - f(); - envs.pop(); - } - - function nop() {} - - function computeForScopedExpression(node) { - scoped(function() { compute(node.expression); }); - } - - function computeParams(node) { - var env = envs[envs.length - 1], params = {}, name; - - for (name in env) { - params[name] = env[name]; - } - node.params = params; - } - - var compute = buildNodeVisitor({ - grammar: - function(node) { - each(node.rules, compute); - }, - - rule: computeForScopedExpression, - - choice: - function(node) { - scoped(function() { each(node.alternatives, compute); }); - }, - - sequence: - function(node) { - var env = envs[envs.length - 1], name; - - function fixup(name) { - each(pluck(node.elements, "resultVar"), function(resultVar, i) { - if ((new RegExp("^" + resultVar + "(\\[\\d+\\])*$")).test(env[name])) { - env[name] = node.resultVar + "[" + i + "]" - + env[name].substr(resultVar.length); - } - }); - } - - each(node.elements, compute); - - for (name in env) { - fixup(name); - } - }, - - labeled: - function(node) { - envs[envs.length - 1][node.label] = node.resultVar; - - scoped(function() { compute(node.expression); }); - }, - - simple_and: computeForScopedExpression, - simple_not: computeForScopedExpression, - semantic_and: computeParams, - semantic_not: computeParams, - optional: computeForScopedExpression, - zero_or_more: computeForScopedExpression, - one_or_more: computeForScopedExpression, - - action: - function(node) { - scoped(function() { - compute(node.expression); - computeParams(node); - }); - }, - - rule_ref: nop, - literal: nop, - any: nop, - "class": nop - }); - - compute(ast); - } -}; -/* Emits the generated code for the AST. */ -PEG.compiler.emitter = function(ast, options) { - options = options || {}; - if (options.cache === undefined) { - options.cache = false; - } - if (options.trackLineAndColumn === undefined) { - options.trackLineAndColumn = false; - } - - /* - * Codie 1.1.0 - * - * https://github.com/dmajda/codie - * - * Copyright (c) 2011-2012 David Majda - * Licensend under the MIT license. - */ - var Codie = (function(undefined) { - - function stringEscape(s) { - function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } - - /* - * 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 control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used - * because JSHint does not like the first and IE the second. - */ - return s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing double quote - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) - .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) - .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); - } - - function push(s) { return '__p.push(' + s + ');'; } - - function pushRaw(template, length, state) { - function unindent(code, level, unindentFirst) { - return code.replace( - new RegExp('^.{' + level +'}', "gm"), - function(str, offset) { - if (offset === 0) { - return unindentFirst ? '' : str; - } else { - return ""; - } - } - ); - } - - var escaped = stringEscape(unindent( - template.substring(0, length), - state.indentLevel(), - state.atBOL - )); - - return escaped.length > 0 ? push('"' + escaped + '"') : ''; - } - - - var Codie = { - /* Codie version (uses semantic versioning). */ - VERSION: "1.1.0", - - /* - * Specifies by how many characters do #if/#else and #for unindent their - * content in the generated code. - */ - indentStep: 2, - - /* Description of #-commands. Extend to define your own commands. */ - commands: { - "if": { - params: /^(.*)$/, - compile: function(state, prefix, params) { - return ['if(' + params[0] + '){', []]; - }, - stackOp: "push" - }, - "else": { - params: /^$/, - compile: function(state) { - var stack = state.commandStack, - insideElse = stack[stack.length - 1] === "else", - insideIf = stack[stack.length - 1] === "if"; - - if (insideElse) { throw new Error("Multiple #elses."); } - if (!insideIf) { throw new Error("Using #else outside of #if."); } - - return ['}else{', []]; - }, - stackOp: "replace" - }, - "for": { - params: /^([a-zA-Z_][a-zA-Z0-9_]*)[ \t]+in[ \t]+(.*)$/, - init: function(state) { - state.forCurrLevel = 0; // current level of #for loop nesting - state.forMaxLevel = 0; // maximum level of #for loop nesting - }, - compile: function(state, prefix, params) { - var c = '__c' + state.forCurrLevel, // __c for "collection" - l = '__l' + state.forCurrLevel, // __l for "length" - i = '__i' + state.forCurrLevel; // __i for "index" - - state.forCurrLevel++; - if (state.forMaxLevel < state.forCurrLevel) { - state.forMaxLevel = state.forCurrLevel; - } - - return [ - c + '=' + params[1] + ';' - + l + '=' + c + '.length;' - + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){' - + params[0] + '=' + c + '[' + i + '];', - [params[0], c, l, i] - ]; - }, - exit: function(state) { state.forCurrLevel--; }, - stackOp: "push" - }, - "end": { - params: /^$/, - compile: function(state) { - var stack = state.commandStack, exit; - - if (stack.length === 0) { throw new Error("Too many #ends."); } - - exit = Codie.commands[stack[stack.length - 1]].exit; - if (exit) { exit(state); } - - return ['}', []]; - }, - stackOp: "pop" - }, - "block": { - params: /^(.*)$/, - compile: function(state, prefix, params) { - var x = '__x', // __x for "prefix", - n = '__n', // __n for "lines" - l = '__l', // __l for "length" - i = '__i'; // __i for "index" - - /* - * Originally, the generated code used |String.prototype.replace|, but - * it is buggy in certain versions of V8 so it was rewritten. See the - * tests for details. - */ - return [ - x + '="' + stringEscape(prefix.substring(state.indentLevel())) + '";' - + n + '=(' + params[0] + ').toString().split("\\n");' - + l + '=' + n + '.length;' - + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){' - + n + '[' + i +']=' + x + '+' + n + '[' + i + ']+"\\n";' - + '}' - + push(n + '.join("")'), - [x, n, l, i] - ]; - }, - stackOp: "nop" - } - }, - - /* - * Compiles a template into a function. When called, this function will - * execute the template in the context of an object passed in a parameter and - * return the result. - */ - template: function(template) { - var stackOps = { - push: function(stack, name) { stack.push(name); }, - replace: function(stack, name) { stack[stack.length - 1] = name; }, - pop: function(stack) { stack.pop(); }, - nop: function() { } - }; - - function compileExpr(state, expr) { - state.atBOL = false; - return [push(expr), []]; - } - - function compileCommand(state, prefix, name, params) { - var command, match, result; - - command = Codie.commands[name]; - if (!command) { throw new Error("Unknown command: #" + name + "."); } - - match = command.params.exec(params); - if (match === null) { - throw new Error( - "Invalid params for command #" + name + ": " + params + "." - ); - } - - result = command.compile(state, prefix, match.slice(1)); - stackOps[command.stackOp](state.commandStack, name); - state.atBOL = true; - return result; - } - - var state = { // compilation state - commandStack: [], // stack of commands as they were nested - atBOL: true, // is the next character to process at BOL? - indentLevel: function() { - return Codie.indentStep * this.commandStack.length; - } - }, - code = '', // generated template function code - vars = ['__p=[]'], // variables used by generated code - name, match, result, i; - - /* Initialize state. */ - for (name in Codie.commands) { - if (Codie.commands[name].init) { Codie.commands[name].init(state); } - } - - /* Compile the template. */ - while ((match = /^([ \t]*)#([a-zA-Z_][a-zA-Z0-9_]*)(?:[ \t]+([^ \t\n][^\n]*))?[ \t]*(?:\n|$)|#\{([^}]*)\}/m.exec(template)) !== null) { - code += pushRaw(template, match.index, state); - result = match[2] !== undefined && match[2] !== "" - ? compileCommand(state, match[1], match[2], match[3] || "") // #-command - : compileExpr(state, match[4]); // #{...} - code += result[0]; - vars = vars.concat(result[1]); - template = template.substring(match.index + match[0].length); - } - code += pushRaw(template, template.length, state); - - /* Check the final state. */ - if (state.commandStack.length > 0) { throw new Error("Missing #end."); } - - /* Sanitize the list of variables used by commands. */ - vars.sort(); - for (i = 0; i < vars.length; i++) { - if (vars[i] === vars[i - 1]) { vars.splice(i--, 1); } - } - - /* Create the resulting function. */ - return new Function("__v", [ - '__v=__v||{};', - 'var ' + vars.join(',') + ';', - 'with(__v){', - code, - 'return __p.join("").replace(/^\\n+|\\n+$/g,"");};' - ].join('')); - } - }; - - return Codie; - - })(); - - var templates = (function() { - var name, - templates = {}, - sources = { - grammar: [ - '(function(){', - ' /*', - ' * Generated by PEG.js 0.7.0.', - ' *', - ' * http://pegjs.majda.cz/', - ' */', - ' ', - /* 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.', - ' *', - ' * For portability, we also escape escape all control and non-ASCII', - ' * characters. Note that "\\0" and "\\v" escape sequences are not used', - ' * because JSHint does not like the first and IE the second.', - ' */', - ' return \'"\' + s', - ' .replace(/\\\\/g, \'\\\\\\\\\') // backslash', - ' .replace(/"/g, \'\\\\"\') // closing quote character', - ' .replace(/\\x08/g, \'\\\\b\') // backspace', - ' .replace(/\\t/g, \'\\\\t\') // horizontal tab', - ' .replace(/\\n/g, \'\\\\n\') // line feed', - ' .replace(/\\f/g, \'\\\\f\') // form feed', - ' .replace(/\\r/g, \'\\\\r\') // carriage return', - ' .replace(/[\\x00-\\x07\\x0B\\x0E-\\x1F\\x80-\\uFFFF]/g, escape)', - ' + \'"\';', - ' }', - ' ', - ' 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 = {', - ' #for rule in node.rules', - ' #{string(rule.name) + ": parse_" + rule.name + (rule !== node.rules[node.rules.length - 1] ? "," : "")}', - ' #end', - ' };', - ' ', - ' if (startRule !== undefined) {', - ' if (parseFunctions[startRule] === undefined) {', - ' throw new Error("Invalid rule name: " + quote(startRule) + ".");', - ' }', - ' } else {', - ' startRule = #{string(node.startRule)};', - ' }', - ' ', - ' #{posInit("pos")};', - ' var reportFailures = 0;', // 0 = report, anything > 0 = do not report - ' #{posInit("rightmostFailuresPos")};', - ' var rightmostFailuresExpected = [];', - ' #if options.cache', - ' var cache = {};', - ' #end', - ' ', - /* 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);', - ' var escapeChar;', - ' var length;', - ' ', - ' if (charCode <= 0xFF) {', - ' escapeChar = \'x\';', - ' length = 2;', - ' } else {', - ' escapeChar = \'u\';', - ' length = 4;', - ' }', - ' ', - ' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);', - ' }', - ' ', - ' #if options.trackLineAndColumn', - ' function clone(object) {', - ' var result = {};', - ' for (var key in object) {', - ' result[key] = object[key];', - ' }', - ' return result;', - ' }', - ' ', - ' function advance(pos, n) {', - ' var endOffset = pos.offset + n;', - ' ', - ' for (var offset = pos.offset; offset < endOffset; offset++) {', - ' var ch = input.charAt(offset);', - ' if (ch === "\\n") {', - ' if (!pos.seenCR) { pos.line++; }', - ' pos.column = 1;', - ' pos.seenCR = false;', - ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {', - ' pos.line++;', - ' pos.column = 1;', - ' pos.seenCR = true;', - ' } else {', - ' pos.column++;', - ' pos.seenCR = false;', - ' }', - ' }', - ' ', - ' pos.offset += n;', - ' }', - ' ', - ' #end', - ' function matchFailed(failure) {', - ' if (#{posOffset("pos")} < #{posOffset("rightmostFailuresPos")}) {', - ' return;', - ' }', - ' ', - ' if (#{posOffset("pos")} > #{posOffset("rightmostFailuresPos")}) {', - ' rightmostFailuresPos = #{posClone("pos")};', - ' rightmostFailuresExpected = [];', - ' }', - ' ', - ' rightmostFailuresExpected.push(failure);', - ' }', - ' ', - ' #for rule in node.rules', - ' #block emit(rule)', - ' ', - ' #end', - ' ', - ' function cleanupExpected(expected) {', - ' expected.sort();', - ' ', - ' var lastExpected = null;', - ' var cleanExpected = [];', - ' for (var i = 0; i < expected.length; i++) {', - ' if (expected[i] !== lastExpected) {', - ' cleanExpected.push(expected[i]);', - ' lastExpected = expected[i];', - ' }', - ' }', - ' return cleanExpected;', - ' }', - ' ', - ' #if !options.trackLineAndColumn', - ' function computeErrorPosition() {', - ' /*', - ' * The first idea was to use |String.split| to break the input up to the', - ' * error position along newlines and derive the line and column from', - ' * there. However IE\'s |split| implementation is so broken that it was', - ' * enough to prevent it.', - ' */', - ' ', - ' var line = 1;', - ' var column = 1;', - ' var seenCR = false;', - ' ', - ' for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {', - ' var ch = input.charAt(i);', - ' if (ch === "\\n") {', - ' if (!seenCR) { line++; }', - ' column = 1;', - ' seenCR = false;', - ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {', - ' line++;', - ' column = 1;', - ' seenCR = true;', - ' } else {', - ' column++;', - ' seenCR = false;', - ' }', - ' }', - ' ', - ' return { line: line, column: column };', - ' }', - ' #end', - ' ', - ' #if node.initializer', - ' #block emit(node.initializer)', - ' #end', - ' ', - ' 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|', - ' * - |#{posOffset("pos")} === input.length|', - ' * - |rightmostFailuresExpected| may or may not contain something', - ' *', - ' * 2. The parser successfully parsed only a part of the input.', - ' *', - ' * - |result !== null|', - ' * - |#{posOffset("pos")} < input.length|', - ' * - |rightmostFailuresExpected| may or may not contain something', - ' *', - ' * 3. The parser did not successfully parse any part of the input.', - ' *', - ' * - |result === null|', - ' * - |#{posOffset("pos")} === 0|', - ' * - |rightmostFailuresExpected| contains at least one failure', - ' *', - ' * All code following this comment (including called functions) must', - ' * handle these states.', - ' */', - ' if (result === null || #{posOffset("pos")} !== input.length) {', - ' var offset = Math.max(#{posOffset("pos")}, #{posOffset("rightmostFailuresPos")});', - ' var found = offset < input.length ? input.charAt(offset) : null;', - ' #if options.trackLineAndColumn', - ' var errorPosition = #{posOffset("pos")} > #{posOffset("rightmostFailuresPos")} ? pos : rightmostFailuresPos;', - ' #else', - ' var errorPosition = computeErrorPosition();', - ' #end', - ' ', - ' throw new this.SyntaxError(', - ' cleanupExpected(rightmostFailuresExpected),', - ' found,', - ' offset,', - ' 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(expected, found, offset, line, column) {', - ' function buildMessage(expected, found) {', - ' var expectedHumanized, foundHumanized;', - ' ', - ' switch (expected.length) {', - ' case 0:', - ' expectedHumanized = "end of input";', - ' break;', - ' case 1:', - ' expectedHumanized = expected[0];', - ' break;', - ' default:', - ' expectedHumanized = expected.slice(0, expected.length - 1).join(", ")', - ' + " or "', - ' + expected[expected.length - 1];', - ' }', - ' ', - ' foundHumanized = found ? quote(found) : "end of input";', - ' ', - ' return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";', - ' }', - ' ', - ' this.name = "SyntaxError";', - ' this.expected = expected;', - ' this.found = found;', - ' this.message = buildMessage(expected, found);', - ' this.offset = offset;', - ' this.line = line;', - ' this.column = column;', - ' };', - ' ', - ' result.SyntaxError.prototype = Error.prototype;', - ' ', - ' return result;', - '})()' - ], - rule: [ - 'function parse_#{node.name}() {', - ' #if options.cache', - ' var cacheKey = "#{node.name}@" + #{posOffset("pos")};', - ' var cachedResult = cache[cacheKey];', - ' if (cachedResult) {', - ' pos = #{posClone("cachedResult.nextPos")};', - ' return cachedResult.result;', - ' }', - ' ', - ' #end', - ' #if node.resultVars.length > 0', - ' var #{node.resultVars.join(", ")};', - ' #end', - ' #if node.posVars.length > 0', - ' var #{node.posVars.join(", ")};', - ' #end', - ' ', - ' #if node.displayName !== null', - ' reportFailures++;', - ' #end', - ' #block emit(node.expression)', - ' #if node.displayName !== null', - ' reportFailures--;', - ' if (reportFailures === 0 && #{node.resultVar} === null) {', - ' matchFailed(#{string(node.displayName)});', - ' }', - ' #end', - ' #if options.cache', - ' ', - ' cache[cacheKey] = {', - ' nextPos: #{posClone("pos")},', - ' result: #{node.resultVar}', - ' };', - ' #end', - ' return #{node.resultVar};', - '}' - ], - choice: [ - '#block emit(alternative)', - '#block nextAlternativesCode' - ], - "choice.next": [ - 'if (#{node.resultVar} === null) {', - ' #block code', - '}' - ], - sequence: [ - '#{posSave(node)};', - '#block code' - ], - "sequence.iteration": [ - '#block emit(element)', - 'if (#{element.resultVar} !== null) {', - ' #block code', - '} else {', - ' #{node.resultVar} = null;', - ' #{posRestore(node)};', - '}' - ], - "sequence.inner": [ - '#{node.resultVar} = [#{pluck(node.elements, "resultVar").join(", ")}];' - ], - simple_and: [ - '#{posSave(node)};', - 'reportFailures++;', - '#block emit(node.expression)', - 'reportFailures--;', - 'if (#{node.resultVar} !== null) {', - ' #{node.resultVar} = "";', - ' #{posRestore(node)};', - '} else {', - ' #{node.resultVar} = null;', - '}' - ], - simple_not: [ - '#{posSave(node)};', - 'reportFailures++;', - '#block emit(node.expression)', - 'reportFailures--;', - 'if (#{node.resultVar} === null) {', - ' #{node.resultVar} = "";', - '} else {', - ' #{node.resultVar} = null;', - ' #{posRestore(node)};', - '}' - ], - semantic_and: [ - '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? "" : null;' - ], - semantic_not: [ - '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? null : "";' - ], - optional: [ - '#block emit(node.expression)', - '#{node.resultVar} = #{node.resultVar} !== null ? #{node.resultVar} : "";' - ], - zero_or_more: [ - '#{node.resultVar} = [];', - '#block emit(node.expression)', - 'while (#{node.expression.resultVar} !== null) {', - ' #{node.resultVar}.push(#{node.expression.resultVar});', - ' #block emit(node.expression)', - '}' - ], - one_or_more: [ - '#block emit(node.expression)', - 'if (#{node.expression.resultVar} !== null) {', - ' #{node.resultVar} = [];', - ' while (#{node.expression.resultVar} !== null) {', - ' #{node.resultVar}.push(#{node.expression.resultVar});', - ' #block emit(node.expression)', - ' }', - '} else {', - ' #{node.resultVar} = null;', - '}' - ], - action: [ - '#{posSave(node)};', - '#block emit(node.expression)', - 'if (#{node.resultVar} !== null) {', - ' #{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? [node.posVar + ".offset", node.posVar + ".line", node.posVar + ".column"] : [node.posVar]).concat(values(node.params)).join(", ")});', - '}', - 'if (#{node.resultVar} === null) {', - ' #{posRestore(node)};', - '}' - ], - rule_ref: [ - '#{node.resultVar} = parse_#{node.name}();' - ], - literal: [ - '#if node.value.length === 0', - ' #{node.resultVar} = "";', - '#else', - ' #if !node.ignoreCase', - ' #if node.value.length === 1', - ' if (input.charCodeAt(#{posOffset("pos")}) === #{node.value.charCodeAt(0)}) {', - ' #else', - ' if (input.substr(#{posOffset("pos")}, #{node.value.length}) === #{string(node.value)}) {', - ' #end', - ' #else', - /* - * One-char literals are not optimized when case-insensitive - * matching is enabled. This is because there is no simple way to - * lowercase a character code that works for character outside ASCII - * letters. Moreover, |toLowerCase| can change string length, - * meaning the result of lowercasing a character can be more - * characters. - */ - ' if (input.substr(#{posOffset("pos")}, #{node.value.length}).toLowerCase() === #{string(node.value.toLowerCase())}) {', - ' #end', - ' #if !node.ignoreCase', - ' #{node.resultVar} = #{string(node.value)};', - ' #else', - ' #{node.resultVar} = input.substr(#{posOffset("pos")}, #{node.value.length});', - ' #end', - ' #{posAdvance(node.value.length)};', - ' } else {', - ' #{node.resultVar} = null;', - ' if (reportFailures === 0) {', - ' matchFailed(#{string(string(node.value))});', - ' }', - ' }', - '#end' - ], - any: [ - 'if (input.length > #{posOffset("pos")}) {', - ' #{node.resultVar} = input.charAt(#{posOffset("pos")});', - ' #{posAdvance(1)};', - '} else {', - ' #{node.resultVar} = null;', - ' if (reportFailures === 0) {', - ' matchFailed("any character");', - ' }', - '}' - ], - "class": [ - 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {', - ' #{node.resultVar} = input.charAt(#{posOffset("pos")});', - ' #{posAdvance(1)};', - '} else {', - ' #{node.resultVar} = null;', - ' if (reportFailures === 0) {', - ' matchFailed(#{string(node.rawText)});', - ' }', - '}' - ] - }; - - for (name in sources) { - templates[name] = Codie.template(sources[name].join('\n')); - } - - return templates; - })(); - - function fill(name, vars) { - vars.string = quote; - vars.pluck = pluck; - vars.keys = keys; - vars.values = values; - vars.emit = emit; - vars.options = options; - - /* Position-handling macros */ - if (options.trackLineAndColumn) { - vars.posInit = function(name) { - return "var " - + name - + " = " - + "{ offset: 0, line: 1, column: 1, seenCR: false }"; - }; - vars.posClone = function(name) { return "clone(" + name + ")"; }; - vars.posOffset = function(name) { return name + ".offset"; }; - - vars.posAdvance = function(n) { return "advance(pos, " + n + ")"; }; - } else { - vars.posInit = function(name) { return "var " + name + " = 0"; }; - vars.posClone = function(name) { return name; }; - vars.posOffset = function(name) { return name; }; - - vars.posAdvance = function(n) { - return n === 1 ? "pos++" : "pos += " + n; - }; - } - vars.posSave = function(node) { - return node.posVar + " = " + vars.posClone("pos"); - }; - vars.posRestore = function(node) { - return "pos" + " = " + vars.posClone(node.posVar); - }; - - return templates[name](vars); - } - - function emitSimple(name) { - return function(node) { return fill(name, { node: node }); }; - } - - var emit = buildNodeVisitor({ - grammar: emitSimple("grammar"), - - initializer: function(node) { return node.code; }, - - rule: emitSimple("rule"), - - /* - * The contract for all code fragments generated by the following functions - * is as follows. - * - * The code fragment tries 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| to point to - * the first chracter following the matched part of the input and sets - * variable with a name stored in |node.resultVar| to an appropriate - * value. This value is always non-|null|. - * - * * If the code fragment does not match the input, it returns with |pos| - * set to the original value and it sets a variable with a name stored in - * |node.resultVar| to |null|. - * - * The code can use variables with names stored in |resultVar| and |posVar| - * properties of the current node's subnodes. It can't use any other - * variables. - */ - - choice: function(node) { - var code, nextAlternativesCode; - - for (var i = node.alternatives.length - 1; i >= 0; i--) { - nextAlternativesCode = i !== node.alternatives.length - 1 - ? fill("choice.next", { node: node, code: code }) - : ''; - code = fill("choice", { - alternative: node.alternatives[i], - nextAlternativesCode: nextAlternativesCode - }); - } - - return code; - }, - - sequence: function(node) { - var code = fill("sequence.inner", { node: node }); - - for (var i = node.elements.length - 1; i >= 0; i--) { - code = fill("sequence.iteration", { - node: node, - element: node.elements[i], - code: code - }); - } - - return fill("sequence", { node: node, code: code }); - }, - - labeled: function(node) { return emit(node.expression); }, - - simple_and: emitSimple("simple_and"), - simple_not: emitSimple("simple_not"), - semantic_and: emitSimple("semantic_and"), - semantic_not: emitSimple("semantic_not"), - optional: emitSimple("optional"), - zero_or_more: emitSimple("zero_or_more"), - one_or_more: emitSimple("one_or_more"), - action: emitSimple("action"), - rule_ref: emitSimple("rule_ref"), - literal: emitSimple("literal"), - any: emitSimple("any"), - - "class": function(node) { - var regexp; - - if (node.parts.length > 0) { - regexp = '/^[' - + (node.inverted ? '^' : '') - + map(node.parts, function(part) { - return part instanceof Array - ? quoteForRegexpClass(part[0]) - + '-' - + quoteForRegexpClass(part[1]) - : quoteForRegexpClass(part); - }).join('') - + ']/' + (node.ignoreCase ? 'i' : ''); - } else { - /* - * Stupid IE considers regexps /[]/ and /[^]/ syntactically invalid, so - * we translate them into euqivalents it can handle. - */ - regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/'; - } - - return fill("class", { node: node, regexp: regexp }); - } - }); - - return emit(ast); -}; - -return PEG; - -})(); - -if (typeof module !== "undefined") { - module.exports = PEG; -}