cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject [09/32] ios commit: CB-11445 Updated checked-in node_modules
Date Fri, 17 Jun 2016 06:17:20 GMT
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/examples/json.pegjs
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/examples/json.pegjs b/node_modules/pegjs/examples/json.pegjs
index f2a34b1..946589e 100644
--- a/node_modules/pegjs/examples/json.pegjs
+++ b/node_modules/pegjs/examples/json.pegjs
@@ -1,120 +1,132 @@
-/* JSON parser based on the grammar described at http://json.org/. */
+/*
+ * JSON Grammar
+ * ============
+ *
+ * Based on the grammar from RFC 7159 [1].
+ *
+ * Note that JSON is also specified in ECMA-262 [2], ECMA-404 [3], and on the
+ * JSON website [4] (somewhat informally). The RFC seems the most authoritative
+ * source, which is confirmed e.g. by [5].
+ *
+ * [1] http://tools.ietf.org/html/rfc7159
+ * [2] http://www.ecma-international.org/publications/standards/Ecma-262.htm
+ * [3] http://www.ecma-international.org/publications/standards/Ecma-404.htm
+ * [4] http://json.org/
+ * [5] https://www.tbray.org/ongoing/When/201x/2014/03/05/RFC7159-JSON
+ */
 
-/* ===== Syntactical Elements ===== */
+/* ----- 2. JSON Grammar ----- */
 
-start
-  = _ object:object { return object; }
+JSON_text
+  = ws value:value ws { return value; }
 
-object
-  = "{" _ "}" _                 { return {};      }
-  / "{" _ members:members "}" _ { return members; }
-
-members
-  = head:pair tail:("," _ pair)* {
-      var result = {};
-      result[head[0]] = head[1];
-      for (var i = 0; i < tail.length; i++) {
-        result[tail[i][2][0]] = tail[i][2][1];
-      }
-      return result;
-    }
+begin_array     = ws "[" ws
+begin_object    = ws "{" ws
+end_array       = ws "]" ws
+end_object      = ws "}" ws
+name_separator  = ws ":" ws
+value_separator = ws "," ws
 
-pair
-  = name:string ":" _ value:value { return [name, value]; }
+ws "whitespace" = [ \t\n\r]*
 
-array
-  = "[" _ "]" _                   { return [];       }
-  / "[" _ elements:elements "]" _ { return elements; }
-
-elements
-  = head:value tail:("," _ value)* {
-      var result = [head];
-      for (var i = 0; i < tail.length; i++) {
-        result.push(tail[i][2]);
-      }
-      return result;
-    }
+/* ----- 3. Values ----- */
 
 value
-  = string
-  / number
+  = false
+  / null
+  / true
   / object
   / array
-  / "true" _  { return true;   }
-  / "false" _ { return false;  }
-  // FIXME: We can't return null here because that would mean parse failure.
-  / "null" _  { return "null"; }
-
-/* ===== Lexical Elements ===== */
-
-string "string"
-  = '"' '"' _             { return "";    }
-  / '"' chars:chars '"' _ { return chars; }
+  / number
+  / string
 
-chars
-  = chars:char+ { return chars.join(""); }
+false = "false" { return false; }
+null  = "null"  { return null;  }
+true  = "true"  { return true;  }
 
-char
-  // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character"
-  = [^"\\\0-\x1F\x7f]
-  / '\\"'  { return '"';  }
-  / "\\\\" { return "\\"; }
-  / "\\/"  { return "/";  }
-  / "\\b"  { return "\b"; }
-  / "\\f"  { return "\f"; }
-  / "\\n"  { return "\n"; }
-  / "\\r"  { return "\r"; }
-  / "\\t"  { return "\t"; }
-  / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
-      return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
-    }
+/* ----- 4. Objects ----- */
 
-number "number"
-  = int_:int frac:frac exp:exp _ { return parseFloat(int_ + frac + exp); }
-  / int_:int frac:frac _         { return parseFloat(int_ + frac);       }
-  / int_:int exp:exp _           { return parseFloat(int_ + exp);        }
-  / int_:int _                   { return parseFloat(int_);              }
+object
+  = begin_object
+    members:(
+      first:member
+      rest:(value_separator m:member { return m; })*
+      {
+        var result = {}, i;
 
-int
-  = digit19:digit19 digits:digits     { return digit19 + digits;       }
-  / digit:digit
-  / "-" digit19:digit19 digits:digits { return "-" + digit19 + digits; }
-  / "-" digit:digit                   { return "-" + digit;            }
+        result[first.name] = first.value;
 
-frac
-  = "." digits:digits { return "." + digits; }
+        for (i = 0; i < rest.length; i++) {
+          result[rest[i].name] = rest[i].value;
+        }
 
-exp
-  = e:e digits:digits { return e + digits; }
+        return result;
+      }
+    )?
+    end_object
+    { return members !== null ? members: {}; }
 
-digits
-  = digits:digit+ { return digits.join(""); }
+member
+  = name:string name_separator value:value {
+      return { name: name, value: value };
+    }
 
-e
-  = e:[eE] sign:[+-]? { return e + sign; }
+/* ----- 5. Arrays ----- */
 
-/*
- * The following rules are not present in the original JSON gramar, but they are
- * assumed to exist implicitly.
- *
- * FIXME: Define them according to ECMA-262, 5th ed.
- */
+array
+  = begin_array
+    values:(
+      first:value
+      rest:(value_separator v:value { return v; })*
+      { return [first].concat(rest); }
+    )?
+    end_array
+    { return values !== null ? values : []; }
 
-digit
-  = [0-9]
+/* ----- 6. Numbers ----- */
 
-digit19
-  = [1-9]
+number "number"
+  = minus? int frac? exp? { return parseFloat(text()); }
 
-hexDigit
-  = [0-9a-fA-F]
+decimal_point = "."
+digit1_9      = [1-9]
+e             = [eE]
+exp           = e (minus / plus)? DIGIT+
+frac          = decimal_point DIGIT+
+int           = zero / (digit1_9 DIGIT*)
+minus         = "-"
+plus          = "+"
+zero          = "0"
 
-/* ===== Whitespace ===== */
+/* ----- 7. Strings ----- */
 
-_ "whitespace"
-  = whitespace*
+string "string"
+  = quotation_mark chars:char* quotation_mark { return chars.join(""); }
 
-// Whitespace is undefined in the original JSON grammar, so I assume a simple
-// conventional definition consistent with ECMA-262, 5th ed.
-whitespace
-  = [ \t\n\r]
+char
+  = unescaped
+  / escape
+    sequence:(
+        '"'
+      / "\\"
+      / "/"
+      / "b" { return "\b"; }
+      / "f" { return "\f"; }
+      / "n" { return "\n"; }
+      / "r" { return "\r"; }
+      / "t" { return "\t"; }
+      / "u" digits:$(HEXDIG HEXDIG HEXDIG HEXDIG) {
+          return String.fromCharCode(parseInt(digits, 16));
+        }
+    )
+    { return sequence; }
+
+escape         = "\\"
+quotation_mark = '"'
+unescaped      = [\x20-\x21\x23-\x5B\x5D-\u10FFFF]
+
+/* ----- Core ABNF Rules ----- */
+
+/* See RFC 4234, Appendix B (http://tools.ietf.org/html/rfc4627). */
+DIGIT  = [0-9]
+HEXDIG = [0-9a-f]i

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler.js b/node_modules/pegjs/lib/compiler.js
new file mode 100644
index 0000000..4ea66eb
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler.js
@@ -0,0 +1,60 @@
+"use strict";
+
+var arrays  = require("./utils/arrays"),
+    objects = require("./utils/objects");
+
+var compiler = {
+  /*
+   * 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|.
+   */
+  passes: {
+    check: {
+      reportMissingRules:  require("./compiler/passes/report-missing-rules"),
+      reportLeftRecursion: require("./compiler/passes/report-left-recursion"),
+      reportInfiniteLoops: require("./compiler/passes/report-infinite-loops")
+    },
+    transform: {
+      removeProxyRules:    require("./compiler/passes/remove-proxy-rules")
+    },
+    generate: {
+      generateBytecode:    require("./compiler/passes/generate-bytecode"),
+      generateJavascript:  require("./compiler/passes/generate-javascript")
+    }
+  },
+
+  /*
+   * 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, passes) {
+    var options = arguments.length > 2 ? objects.clone(arguments[2]) : {},
+        stage;
+
+    objects.defaults(options, {
+      allowedStartRules:  [ast.rules[0].name],
+      cache:              false,
+      trace:              false,
+      optimize:           "speed",
+      output:             "parser"
+    });
+
+    for (stage in passes) {
+      if (passes.hasOwnProperty(stage)) {
+        arrays.each(passes[stage], function(p) { p(ast, options); });
+      }
+    }
+
+    switch (options.output) {
+      case "parser": return eval(ast.code);
+      case "source": return ast.code;
+    }
+  }
+};
+
+module.exports = compiler;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/asts.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/asts.js b/node_modules/pegjs/lib/compiler/asts.js
new file mode 100644
index 0000000..aad50a6
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/asts.js
@@ -0,0 +1,64 @@
+"use strict";
+
+var arrays  = require("../utils/arrays"),
+    visitor = require("./visitor");
+
+/* AST utilities. */
+var asts = {
+  findRule: function(ast, name) {
+    return arrays.find(ast.rules, function(r) { return r.name === name; });
+  },
+
+  indexOfRule: function(ast, name) {
+    return arrays.indexOf(ast.rules, function(r) { return r.name === name; });
+  },
+
+  alwaysAdvancesOnSuccess: function(ast, node) {
+    function advancesTrue()  { return true;  }
+    function advancesFalse() { return false; }
+
+    function advancesExpression(node) {
+      return advances(node.expression);
+    }
+
+    var advances = visitor.build({
+      rule:  advancesExpression,
+      named: advancesExpression,
+
+      choice: function(node) {
+        return arrays.every(node.alternatives, advances);
+      },
+
+      action: advancesExpression,
+
+      sequence: function(node) {
+        return arrays.some(node.elements, advances);
+      },
+
+      labeled:      advancesExpression,
+      text:         advancesExpression,
+      simple_and:   advancesFalse,
+      simple_not:   advancesFalse,
+      optional:     advancesFalse,
+      zero_or_more: advancesFalse,
+      one_or_more:  advancesExpression,
+      semantic_and: advancesFalse,
+      semantic_not: advancesFalse,
+
+      rule_ref: function(node) {
+        return advances(asts.findRule(ast, node.name));
+      },
+
+      literal: function(node) {
+        return node.value !== "";
+      },
+
+      "class": advancesTrue,
+      any:     advancesTrue
+    });
+
+    return advances(node);
+  }
+};
+
+module.exports = asts;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/javascript.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/javascript.js b/node_modules/pegjs/lib/compiler/javascript.js
new file mode 100644
index 0000000..bc2ce95
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/javascript.js
@@ -0,0 +1,57 @@
+"use strict";
+
+function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
+
+/* JavaScript code generation helpers. */
+var javascript = {
+  stringEscape: function(s) {
+    /*
+     * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
+     * literal except for the closing quote character, backslash, carriage
+     * return, line separator, paragraph separator, and line feed. Any character
+     * may appear in the form of an escape sequence.
+     *
+     * For portability, we also 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(/[\u0100-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); })
+      .replace(/[\u1000-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); });
+  },
+
+  regexpClassEscape: function(s) {
+    /*
+     * Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
+     *
+     * For portability, we also escape all control and non-ASCII characters.
+     */
+    return s
+      .replace(/\\/g, '\\\\')    // backslash
+      .replace(/\//g, '\\/')     // closing slash
+      .replace(/\]/g, '\\]')     // closing bracket
+      .replace(/\^/g, '\\^')     // caret
+      .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(/[\x00-\x08\x0E\x0F]/g,  function(ch) { return '\\x0' + hex(ch); })
+      .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x'  + hex(ch); })
+      .replace(/[\u0100-\u0FFF]/g,      function(ch) { return '\\u0' + hex(ch); })
+      .replace(/[\u1000-\uFFFF]/g,      function(ch) { return '\\u'  + hex(ch); });
+  }
+};
+
+module.exports = javascript;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/opcodes.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/opcodes.js b/node_modules/pegjs/lib/compiler/opcodes.js
new file mode 100644
index 0000000..4c52008
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/opcodes.js
@@ -0,0 +1,54 @@
+"use strict";
+
+/* Bytecode instruction opcodes. */
+var opcodes = {
+  /* Stack Manipulation */
+
+  PUSH:             0,    // PUSH c
+  PUSH_UNDEFINED:   1,    // PUSH_UNDEFINED
+  PUSH_NULL:        2,    // PUSH_NULL
+  PUSH_FAILED:      3,    // PUSH_FAILED
+  PUSH_EMPTY_ARRAY: 4,    // PUSH_EMPTY_ARRAY
+  PUSH_CURR_POS:    5,    // PUSH_CURR_POS
+  POP:              6,    // POP
+  POP_CURR_POS:     7,    // POP_CURR_POS
+  POP_N:            8,    // POP_N n
+  NIP:              9,    // NIP
+  APPEND:           10,   // APPEND
+  WRAP:             11,   // WRAP n
+  TEXT:             12,   // TEXT
+
+  /* Conditions and Loops */
+
+  IF:               13,   // IF t, f
+  IF_ERROR:         14,   // IF_ERROR t, f
+  IF_NOT_ERROR:     15,   // IF_NOT_ERROR t, f
+  WHILE_NOT_ERROR:  16,   // WHILE_NOT_ERROR b
+
+  /* Matching */
+
+  MATCH_ANY:        17,   // MATCH_ANY a, f, ...
+  MATCH_STRING:     18,   // MATCH_STRING s, a, f, ...
+  MATCH_STRING_IC:  19,   // MATCH_STRING_IC s, a, f, ...
+  MATCH_REGEXP:     20,   // MATCH_REGEXP r, a, f, ...
+  ACCEPT_N:         21,   // ACCEPT_N n
+  ACCEPT_STRING:    22,   // ACCEPT_STRING s
+  FAIL:             23,   // FAIL e
+
+  /* Calls */
+
+  LOAD_SAVED_POS:   24,   // LOAD_SAVED_POS p
+  UPDATE_SAVED_POS: 25,   // UPDATE_SAVED_POS
+  CALL:             26,   // CALL f, n, pc, p1, p2, ..., pN
+
+  /* Rules */
+
+  RULE:             27,   // RULE r
+
+  /* Failure Reporting */
+
+  SILENT_FAILS_ON:  28,   // SILENT_FAILS_ON
+  SILENT_FAILS_OFF: 29    // SILENT_FAILS_OFF
+};
+
+module.exports = opcodes;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js b/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js
new file mode 100644
index 0000000..4aa401f
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js
@@ -0,0 +1,618 @@
+"use strict";
+
+var arrays  = require("../../utils/arrays"),
+    objects = require("../../utils/objects"),
+    asts    = require("../asts"),
+    visitor = require("../visitor"),
+    op      = require("../opcodes"),
+    js      = require("../javascript");
+
+/* Generates bytecode.
+ *
+ * Instructions
+ * ============
+ *
+ * Stack Manipulation
+ * ------------------
+ *
+ *  [0] PUSH c
+ *
+ *        stack.push(consts[c]);
+ *
+ *  [1] PUSH_UNDEFINED
+ *
+ *        stack.push(undefined);
+ *
+ *  [2] PUSH_NULL
+ *
+ *        stack.push(null);
+ *
+ *  [3] PUSH_FAILED
+ *
+ *        stack.push(FAILED);
+ *
+ *  [4] PUSH_EMPTY_ARRAY
+ *
+ *        stack.push([]);
+ *
+ *  [5] PUSH_CURR_POS
+ *
+ *        stack.push(currPos);
+ *
+ *  [6] POP
+ *
+ *        stack.pop();
+ *
+ *  [7] POP_CURR_POS
+ *
+ *        currPos = stack.pop();
+ *
+ *  [8] POP_N n
+ *
+ *        stack.pop(n);
+ *
+ *  [9] NIP
+ *
+ *        value = stack.pop();
+ *        stack.pop();
+ *        stack.push(value);
+ *
+ * [10] APPEND
+ *
+ *        value = stack.pop();
+ *        array = stack.pop();
+ *        array.push(value);
+ *        stack.push(array);
+ *
+ * [11] WRAP n
+ *
+ *        stack.push(stack.pop(n));
+ *
+ * [12] TEXT
+ *
+ *        stack.push(input.substring(stack.pop(), currPos));
+ *
+ * Conditions and Loops
+ * --------------------
+ *
+ * [13] IF t, f
+ *
+ *        if (stack.top()) {
+ *          interpret(ip + 3, ip + 3 + t);
+ *        } else {
+ *          interpret(ip + 3 + t, ip + 3 + t + f);
+ *        }
+ *
+ * [14] IF_ERROR t, f
+ *
+ *        if (stack.top() === FAILED) {
+ *          interpret(ip + 3, ip + 3 + t);
+ *        } else {
+ *          interpret(ip + 3 + t, ip + 3 + t + f);
+ *        }
+ *
+ * [15] IF_NOT_ERROR t, f
+ *
+ *        if (stack.top() !== FAILED) {
+ *          interpret(ip + 3, ip + 3 + t);
+ *        } else {
+ *          interpret(ip + 3 + t, ip + 3 + t + f);
+ *        }
+ *
+ * [16] WHILE_NOT_ERROR b
+ *
+ *        while(stack.top() !== FAILED) {
+ *          interpret(ip + 2, ip + 2 + b);
+ *        }
+ *
+ * Matching
+ * --------
+ *
+ * [17] MATCH_ANY a, f, ...
+ *
+ *        if (input.length > currPos) {
+ *          interpret(ip + 3, ip + 3 + a);
+ *        } else {
+ *          interpret(ip + 3 + a, ip + 3 + a + f);
+ *        }
+ *
+ * [18] MATCH_STRING s, a, f, ...
+ *
+ *        if (input.substr(currPos, consts[s].length) === consts[s]) {
+ *          interpret(ip + 4, ip + 4 + a);
+ *        } else {
+ *          interpret(ip + 4 + a, ip + 4 + a + f);
+ *        }
+ *
+ * [19] MATCH_STRING_IC s, a, f, ...
+ *
+ *        if (input.substr(currPos, consts[s].length).toLowerCase() === consts[s]) {
+ *          interpret(ip + 4, ip + 4 + a);
+ *        } else {
+ *          interpret(ip + 4 + a, ip + 4 + a + f);
+ *        }
+ *
+ * [20] MATCH_REGEXP r, a, f, ...
+ *
+ *        if (consts[r].test(input.charAt(currPos))) {
+ *          interpret(ip + 4, ip + 4 + a);
+ *        } else {
+ *          interpret(ip + 4 + a, ip + 4 + a + f);
+ *        }
+ *
+ * [21] ACCEPT_N n
+ *
+ *        stack.push(input.substring(currPos, n));
+ *        currPos += n;
+ *
+ * [22] ACCEPT_STRING s
+ *
+ *        stack.push(consts[s]);
+ *        currPos += consts[s].length;
+ *
+ * [23] FAIL e
+ *
+ *        stack.push(FAILED);
+ *        fail(consts[e]);
+ *
+ * Calls
+ * -----
+ *
+ * [24] LOAD_SAVED_POS p
+ *
+ *        savedPos = stack[p];
+ *
+ * [25] UPDATE_SAVED_POS
+ *
+ *        savedPos = currPos;
+ *
+ * [26] CALL f, n, pc, p1, p2, ..., pN
+ *
+ *        value = consts[f](stack[p1], ..., stack[pN]);
+ *        stack.pop(n);
+ *        stack.push(value);
+ *
+ * Rules
+ * -----
+ *
+ * [27] RULE r
+ *
+ *        stack.push(parseRule(r));
+ *
+ * Failure Reporting
+ * -----------------
+ *
+ * [28] SILENT_FAILS_ON
+ *
+ *        silentFails++;
+ *
+ * [29] SILENT_FAILS_OFF
+ *
+ *        silentFails--;
+ */
+function generateBytecode(ast) {
+  var consts = [];
+
+  function addConst(value) {
+    var index = arrays.indexOf(consts, value);
+
+    return index === -1 ? consts.push(value) - 1 : index;
+  }
+
+  function addFunctionConst(params, code) {
+    return addConst(
+      "function(" + params.join(", ") + ") {" + code + "}"
+    );
+  }
+
+  function buildSequence() {
+    return Array.prototype.concat.apply([], arguments);
+  }
+
+  function buildCondition(condCode, thenCode, elseCode) {
+    return condCode.concat(
+      [thenCode.length, elseCode.length],
+      thenCode,
+      elseCode
+    );
+  }
+
+  function buildLoop(condCode, bodyCode) {
+    return condCode.concat([bodyCode.length], bodyCode);
+  }
+
+  function buildCall(functionIndex, delta, env, sp) {
+    var params = arrays.map(objects.values(env), function(p) { return sp - p; });
+
+    return [op.CALL, functionIndex, delta, params.length].concat(params);
+  }
+
+  function buildSimplePredicate(expression, negative, context) {
+    return buildSequence(
+      [op.PUSH_CURR_POS],
+      [op.SILENT_FAILS_ON],
+      generate(expression, {
+        sp:     context.sp + 1,
+        env:    objects.clone(context.env),
+        action: null
+      }),
+      [op.SILENT_FAILS_OFF],
+      buildCondition(
+        [negative ? op.IF_ERROR : op.IF_NOT_ERROR],
+        buildSequence(
+          [op.POP],
+          [negative ? op.POP : op.POP_CURR_POS],
+          [op.PUSH_UNDEFINED]
+        ),
+        buildSequence(
+          [op.POP],
+          [negative ? op.POP_CURR_POS : op.POP],
+          [op.PUSH_FAILED]
+        )
+      )
+    );
+  }
+
+  function buildSemanticPredicate(code, negative, context) {
+    var functionIndex = addFunctionConst(objects.keys(context.env), code);
+
+    return buildSequence(
+      [op.UPDATE_SAVED_POS],
+      buildCall(functionIndex, 0, context.env, context.sp),
+      buildCondition(
+        [op.IF],
+        buildSequence(
+          [op.POP],
+          negative ? [op.PUSH_FAILED] : [op.PUSH_UNDEFINED]
+        ),
+        buildSequence(
+          [op.POP],
+          negative ? [op.PUSH_UNDEFINED] : [op.PUSH_FAILED]
+        )
+      )
+    );
+  }
+
+  function buildAppendLoop(expressionCode) {
+    return buildLoop(
+      [op.WHILE_NOT_ERROR],
+      buildSequence([op.APPEND], expressionCode)
+    );
+  }
+
+  var generate = visitor.build({
+    grammar: function(node) {
+      arrays.each(node.rules, generate);
+
+      node.consts = consts;
+    },
+
+    rule: function(node) {
+      node.bytecode = generate(node.expression, {
+        sp:     -1,    // stack pointer
+        env:    { },   // mapping of label names to stack positions
+        action: null   // action nodes pass themselves to children here
+      });
+    },
+
+    named: function(node, context) {
+      var nameIndex = addConst(
+        '{ type: "other", description: "' + js.stringEscape(node.name) + '" }'
+      );
+
+      /*
+       * The code generated below is slightly suboptimal because |FAIL| pushes
+       * to the stack, so we need to stick a |POP| in front of it. We lack a
+       * dedicated instruction that would just report the failure and not touch
+       * the stack.
+       */
+      return buildSequence(
+        [op.SILENT_FAILS_ON],
+        generate(node.expression, context),
+        [op.SILENT_FAILS_OFF],
+        buildCondition([op.IF_ERROR], [op.FAIL, nameIndex], [])
+      );
+    },
+
+    choice: function(node, context) {
+      function buildAlternativesCode(alternatives, context) {
+        return buildSequence(
+          generate(alternatives[0], {
+            sp:     context.sp,
+            env:    objects.clone(context.env),
+            action: null
+          }),
+          alternatives.length > 1
+            ? buildCondition(
+                [op.IF_ERROR],
+                buildSequence(
+                  [op.POP],
+                  buildAlternativesCode(alternatives.slice(1), context)
+                ),
+                []
+              )
+            : []
+        );
+      }
+
+      return buildAlternativesCode(node.alternatives, context);
+    },
+
+    action: function(node, context) {
+      var env            = objects.clone(context.env),
+          emitCall       = node.expression.type !== "sequence"
+                        || node.expression.elements.length === 0,
+          expressionCode = generate(node.expression, {
+            sp:     context.sp + (emitCall ? 1 : 0),
+            env:    env,
+            action: node
+          }),
+          functionIndex  = addFunctionConst(objects.keys(env), node.code);
+
+      return emitCall
+        ? buildSequence(
+            [op.PUSH_CURR_POS],
+            expressionCode,
+            buildCondition(
+              [op.IF_NOT_ERROR],
+              buildSequence(
+                [op.LOAD_SAVED_POS, 1],
+                buildCall(functionIndex, 1, env, context.sp + 2)
+              ),
+              []
+            ),
+            [op.NIP]
+          )
+        : expressionCode;
+    },
+
+    sequence: function(node, context) {
+      function buildElementsCode(elements, context) {
+        var processedCount, functionIndex;
+
+        if (elements.length > 0) {
+          processedCount = node.elements.length - elements.slice(1).length;
+
+          return buildSequence(
+            generate(elements[0], {
+              sp:     context.sp,
+              env:    context.env,
+              action: null
+            }),
+            buildCondition(
+              [op.IF_NOT_ERROR],
+              buildElementsCode(elements.slice(1), {
+                sp:     context.sp + 1,
+                env:    context.env,
+                action: context.action
+              }),
+              buildSequence(
+                processedCount > 1 ? [op.POP_N, processedCount] : [op.POP],
+                [op.POP_CURR_POS],
+                [op.PUSH_FAILED]
+              )
+            )
+          );
+        } else {
+          if (context.action) {
+            functionIndex = addFunctionConst(
+              objects.keys(context.env),
+              context.action.code
+            );
+
+            return buildSequence(
+              [op.LOAD_SAVED_POS, node.elements.length],
+              buildCall(
+                functionIndex,
+                node.elements.length,
+                context.env,
+                context.sp
+              ),
+              [op.NIP]
+            );
+          } else {
+            return buildSequence([op.WRAP, node.elements.length], [op.NIP]);
+          }
+        }
+      }
+
+      return buildSequence(
+        [op.PUSH_CURR_POS],
+        buildElementsCode(node.elements, {
+          sp:     context.sp + 1,
+          env:    context.env,
+          action: context.action
+        })
+      );
+    },
+
+    labeled: function(node, context) {
+      var env = objects.clone(context.env);
+
+      context.env[node.label] = context.sp + 1;
+
+      return generate(node.expression, {
+        sp:     context.sp,
+        env:    env,
+        action: null
+      });
+    },
+
+    text: function(node, context) {
+      return buildSequence(
+        [op.PUSH_CURR_POS],
+        generate(node.expression, {
+          sp:     context.sp + 1,
+          env:    objects.clone(context.env),
+          action: null
+        }),
+        buildCondition(
+          [op.IF_NOT_ERROR],
+          buildSequence([op.POP], [op.TEXT]),
+          [op.NIP]
+        )
+      );
+    },
+
+    simple_and: function(node, context) {
+      return buildSimplePredicate(node.expression, false, context);
+    },
+
+    simple_not: function(node, context) {
+      return buildSimplePredicate(node.expression, true, context);
+    },
+
+    optional: function(node, context) {
+      return buildSequence(
+        generate(node.expression, {
+          sp:     context.sp,
+          env:    objects.clone(context.env),
+          action: null
+        }),
+        buildCondition(
+          [op.IF_ERROR],
+          buildSequence([op.POP], [op.PUSH_NULL]),
+          []
+        )
+      );
+    },
+
+    zero_or_more: function(node, context) {
+      var expressionCode = generate(node.expression, {
+            sp:     context.sp + 1,
+            env:    objects.clone(context.env),
+            action: null
+          });
+
+      return buildSequence(
+        [op.PUSH_EMPTY_ARRAY],
+        expressionCode,
+        buildAppendLoop(expressionCode),
+        [op.POP]
+      );
+    },
+
+    one_or_more: function(node, context) {
+      var expressionCode = generate(node.expression, {
+            sp:     context.sp + 1,
+            env:    objects.clone(context.env),
+            action: null
+          });
+
+      return buildSequence(
+        [op.PUSH_EMPTY_ARRAY],
+        expressionCode,
+        buildCondition(
+          [op.IF_NOT_ERROR],
+          buildSequence(buildAppendLoop(expressionCode), [op.POP]),
+          buildSequence([op.POP], [op.POP], [op.PUSH_FAILED])
+        )
+      );
+    },
+
+    semantic_and: function(node, context) {
+      return buildSemanticPredicate(node.code, false, context);
+    },
+
+    semantic_not: function(node, context) {
+      return buildSemanticPredicate(node.code, true, context);
+    },
+
+    rule_ref: function(node) {
+      return [op.RULE, asts.indexOfRule(ast, node.name)];
+    },
+
+    literal: function(node) {
+      var stringIndex, expectedIndex;
+
+      if (node.value.length > 0) {
+        stringIndex = addConst('"'
+          + js.stringEscape(
+              node.ignoreCase ? node.value.toLowerCase() : node.value
+            )
+          + '"'
+        );
+        expectedIndex = addConst([
+          '{',
+          'type: "literal",',
+          'value: "' + js.stringEscape(node.value) + '",',
+          'description: "'
+             + js.stringEscape('"' + js.stringEscape(node.value) + '"')
+             + '"',
+          '}'
+        ].join(' '));
+
+        /*
+         * For case-sensitive strings the value must match the beginning of the
+         * remaining input exactly. As a result, we can use |ACCEPT_STRING| and
+         * save one |substr| call that would be needed if we used |ACCEPT_N|.
+         */
+        return buildCondition(
+          node.ignoreCase
+            ? [op.MATCH_STRING_IC, stringIndex]
+            : [op.MATCH_STRING, stringIndex],
+          node.ignoreCase
+            ? [op.ACCEPT_N, node.value.length]
+            : [op.ACCEPT_STRING, stringIndex],
+          [op.FAIL, expectedIndex]
+        );
+      } else {
+        stringIndex = addConst('""');
+
+        return [op.PUSH, stringIndex];
+      }
+    },
+
+    "class": function(node) {
+      var regexp, regexpIndex, expectedIndex;
+
+      if (node.parts.length > 0) {
+        regexp = '/^['
+          + (node.inverted ? '^' : '')
+          + arrays.map(node.parts, function(part) {
+              return part instanceof Array
+                ? js.regexpClassEscape(part[0])
+                  + '-'
+                  + js.regexpClassEscape(part[1])
+                : js.regexpClassEscape(part);
+            }).join('')
+          + ']/' + (node.ignoreCase ? 'i' : '');
+      } else {
+        /*
+         * IE considers regexps /[]/ and /[^]/ as syntactically invalid, so we
+         * translate them into euqivalents it can handle.
+         */
+        regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/';
+      }
+
+      regexpIndex   = addConst(regexp);
+      expectedIndex = addConst([
+        '{',
+        'type: "class",',
+        'value: "' + js.stringEscape(node.rawText) + '",',
+        'description: "' + js.stringEscape(node.rawText) + '"',
+        '}'
+      ].join(' '));
+
+      return buildCondition(
+        [op.MATCH_REGEXP, regexpIndex],
+        [op.ACCEPT_N, 1],
+        [op.FAIL, expectedIndex]
+      );
+    },
+
+    any: function() {
+      var expectedIndex = addConst('{ type: "any", description: "any character" }');
+
+      return buildCondition(
+        [op.MATCH_ANY],
+        [op.ACCEPT_N, 1],
+        [op.FAIL, expectedIndex]
+      );
+    }
+  });
+
+  generate(ast);
+}
+
+module.exports = generateBytecode;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/passes/generate-javascript.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/passes/generate-javascript.js b/node_modules/pegjs/lib/compiler/passes/generate-javascript.js
new file mode 100644
index 0000000..c4843f3
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/passes/generate-javascript.js
@@ -0,0 +1,1213 @@
+"use strict";
+
+var arrays = require("../../utils/arrays"),
+    asts   = require("../asts"),
+    op     = require("../opcodes"),
+    js     = require("../javascript");
+
+/* Generates parser JavaScript code. */
+function generateJavascript(ast, options) {
+  /* These only indent non-empty lines to avoid trailing whitespace. */
+  function indent2(code)  { return code.replace(/^(.+)$/gm, '  $1');         }
+  function indent4(code)  { return code.replace(/^(.+)$/gm, '    $1');       }
+  function indent8(code)  { return code.replace(/^(.+)$/gm, '        $1');   }
+  function indent10(code) { return code.replace(/^(.+)$/gm, '          $1'); }
+
+  function generateTables() {
+    if (options.optimize === "size") {
+      return [
+        'peg$consts = [',
+           indent2(ast.consts.join(',\n')),
+        '],',
+        '',
+        'peg$bytecode = [',
+           indent2(arrays.map(ast.rules, function(rule) {
+             return 'peg$decode("'
+                   + js.stringEscape(arrays.map(
+                       rule.bytecode,
+                       function(b) { return String.fromCharCode(b + 32); }
+                     ).join(''))
+                   + '")';
+           }).join(',\n')),
+        '],'
+      ].join('\n');
+    } else {
+      return arrays.map(
+        ast.consts,
+        function(c, i) { return 'peg$c' + i + ' = ' + c + ','; }
+      ).join('\n');
+    }
+  }
+
+  function generateRuleHeader(ruleNameCode, ruleIndexCode) {
+    var parts = [];
+
+    parts.push('');
+
+    if (options.trace) {
+      parts.push([
+        'peg$tracer.trace({',
+        '  type:     "rule.enter",',
+        '  rule:     ' + ruleNameCode + ',',
+        '  location: peg$computeLocation(startPos, startPos)',
+        '});',
+        ''
+      ].join('\n'));
+    }
+
+    if (options.cache) {
+      parts.push([
+        'var key    = peg$currPos * ' + ast.rules.length + ' + ' + ruleIndexCode + ',',
+        '    cached = peg$resultsCache[key];',
+        '',
+        'if (cached) {',
+        '  peg$currPos = cached.nextPos;',
+        '',
+      ].join('\n'));
+
+      if (options.trace) {
+        parts.push([
+          'if (cached.result !== peg$FAILED) {',
+          '  peg$tracer.trace({',
+          '    type:   "rule.match",',
+          '    rule:   ' + ruleNameCode + ',',
+          '    result: cached.result,',
+          '    location: peg$computeLocation(startPos, peg$currPos)',
+          '  });',
+          '} else {',
+          '  peg$tracer.trace({',
+          '    type: "rule.fail",',
+          '    rule: ' + ruleNameCode + ',',
+          '    location: peg$computeLocation(startPos, startPos)',
+          '  });',
+          '}',
+          ''
+        ].join('\n'));
+      }
+
+      parts.push([
+        '  return cached.result;',
+        '}',
+        ''
+      ].join('\n'));
+    }
+
+    return parts.join('\n');
+  }
+
+  function generateRuleFooter(ruleNameCode, resultCode) {
+    var parts = [];
+
+    if (options.cache) {
+      parts.push([
+        '',
+        'peg$resultsCache[key] = { nextPos: peg$currPos, result: ' + resultCode + ' };'
+      ].join('\n'));
+    }
+
+    if (options.trace) {
+      parts.push([
+          '',
+          'if (' + resultCode + ' !== peg$FAILED) {',
+          '  peg$tracer.trace({',
+          '    type:   "rule.match",',
+          '    rule:   ' + ruleNameCode + ',',
+          '    result: ' + resultCode + ',',
+          '    location: peg$computeLocation(startPos, peg$currPos)',
+          '  });',
+          '} else {',
+          '  peg$tracer.trace({',
+          '    type: "rule.fail",',
+          '    rule: ' + ruleNameCode + ',',
+          '    location: peg$computeLocation(startPos, startPos)',
+          '  });',
+          '}'
+      ].join('\n'));
+    }
+
+    parts.push([
+      '',
+      'return ' + resultCode + ';'
+    ].join('\n'));
+
+    return parts.join('\n');
+  }
+
+  function generateInterpreter() {
+    var parts = [];
+
+    function generateCondition(cond, argsLength) {
+      var baseLength      = argsLength + 3,
+          thenLengthCode = 'bc[ip + ' + (baseLength - 2) + ']',
+          elseLengthCode = 'bc[ip + ' + (baseLength - 1) + ']';
+
+      return [
+        'ends.push(end);',
+        'ips.push(ip + ' + baseLength + ' + ' + thenLengthCode + ' + ' + elseLengthCode + ');',
+        '',
+        'if (' + cond + ') {',
+        '  end = ip + ' + baseLength + ' + ' + thenLengthCode + ';',
+        '  ip += ' + baseLength + ';',
+        '} else {',
+        '  end = ip + ' + baseLength + ' + ' + thenLengthCode + ' + ' + elseLengthCode + ';',
+        '  ip += ' + baseLength + ' + ' + thenLengthCode + ';',
+        '}',
+        '',
+        'break;'
+      ].join('\n');
+    }
+
+    function generateLoop(cond) {
+      var baseLength     = 2,
+          bodyLengthCode = 'bc[ip + ' + (baseLength - 1) + ']';
+
+      return [
+        'if (' + cond + ') {',
+        '  ends.push(end);',
+        '  ips.push(ip);',
+        '',
+        '  end = ip + ' + baseLength + ' + ' + bodyLengthCode + ';',
+        '  ip += ' + baseLength + ';',
+        '} else {',
+        '  ip += ' + baseLength + ' + ' + bodyLengthCode + ';',
+        '}',
+        '',
+        'break;'
+      ].join('\n');
+    }
+
+    function generateCall() {
+      var baseLength       = 4,
+          paramsLengthCode = 'bc[ip + ' + (baseLength - 1) + ']';
+
+      return [
+        'params = bc.slice(ip + ' + baseLength + ', ip + ' + baseLength + ' + ' + paramsLengthCode + ');',
+        'for (i = 0; i < ' + paramsLengthCode + '; i++) {',
+        '  params[i] = stack[stack.length - 1 - params[i]];',
+        '}',
+        '',
+        'stack.splice(',
+        '  stack.length - bc[ip + 2],',
+        '  bc[ip + 2],',
+        '  peg$consts[bc[ip + 1]].apply(null, params)',
+        ');',
+        '',
+        'ip += ' + baseLength + ' + ' + paramsLengthCode + ';',
+        'break;'
+      ].join('\n');
+    }
+
+    parts.push([
+      'function peg$decode(s) {',
+      '  var bc = new Array(s.length), i;',
+      '',
+      '  for (i = 0; i < s.length; i++) {',
+      '    bc[i] = s.charCodeAt(i) - 32;',
+      '  }',
+      '',
+      '  return bc;',
+      '}',
+      '',
+      'function peg$parseRule(index) {',
+    ].join('\n'));
+
+    if (options.trace) {
+      parts.push([
+        '  var bc       = peg$bytecode[index],',
+        '      ip       = 0,',
+        '      ips      = [],',
+        '      end      = bc.length,',
+        '      ends     = [],',
+        '      stack    = [],',
+        '      startPos = peg$currPos,',
+        '      params, i;',
+      ].join('\n'));
+    } else {
+      parts.push([
+        '  var bc    = peg$bytecode[index],',
+        '      ip    = 0,',
+        '      ips   = [],',
+        '      end   = bc.length,',
+        '      ends  = [],',
+        '      stack = [],',
+        '      params, i;',
+      ].join('\n'));
+    }
+
+    parts.push(indent2(generateRuleHeader('peg$ruleNames[index]', 'index')));
+
+    parts.push([
+      /*
+       * The point of the outer loop and the |ips| & |ends| stacks is to avoid
+       * recursive calls for interpreting parts of bytecode. In other words, we
+       * implement the |interpret| operation of the abstract machine without
+       * function calls. Such calls would likely slow the parser down and more
+       * importantly cause stack overflows for complex grammars.
+       */
+      '  while (true) {',
+      '    while (ip < end) {',
+      '      switch (bc[ip]) {',
+      '        case ' + op.PUSH + ':',               // PUSH c
+      '          stack.push(peg$consts[bc[ip + 1]]);',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.PUSH_UNDEFINED + ':',     // PUSH_UNDEFINED
+      '          stack.push(void 0);',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.PUSH_NULL + ':',          // PUSH_NULL
+      '          stack.push(null);',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.PUSH_FAILED + ':',        // PUSH_FAILED
+      '          stack.push(peg$FAILED);',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.PUSH_EMPTY_ARRAY + ':',   // PUSH_EMPTY_ARRAY
+      '          stack.push([]);',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.PUSH_CURR_POS + ':',      // PUSH_CURR_POS
+      '          stack.push(peg$currPos);',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.POP + ':',                // POP
+      '          stack.pop();',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.POP_CURR_POS + ':',       // POP_CURR_POS
+      '          peg$currPos = stack.pop();',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.POP_N + ':',              // POP_N n
+      '          stack.length -= bc[ip + 1];',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.NIP + ':',                // NIP
+      '          stack.splice(-2, 1);',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.APPEND + ':',             // APPEND
+      '          stack[stack.length - 2].push(stack.pop());',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.WRAP + ':',               // WRAP n
+      '          stack.push(stack.splice(stack.length - bc[ip + 1], bc[ip + 1]));',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.TEXT + ':',               // TEXT
+      '          stack.push(input.substring(stack.pop(), peg$currPos));',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.IF + ':',                 // IF t, f
+                 indent10(generateCondition('stack[stack.length - 1]', 0)),
+      '',
+      '        case ' + op.IF_ERROR + ':',           // IF_ERROR t, f
+                 indent10(generateCondition(
+                   'stack[stack.length - 1] === peg$FAILED',
+                   0
+                 )),
+      '',
+      '        case ' + op.IF_NOT_ERROR + ':',       // IF_NOT_ERROR t, f
+                 indent10(
+                   generateCondition('stack[stack.length - 1] !== peg$FAILED',
+                   0
+                 )),
+      '',
+      '        case ' + op.WHILE_NOT_ERROR + ':',    // WHILE_NOT_ERROR b
+                 indent10(generateLoop('stack[stack.length - 1] !== peg$FAILED')),
+      '',
+      '        case ' + op.MATCH_ANY + ':',          // MATCH_ANY a, f, ...
+                 indent10(generateCondition('input.length > peg$currPos', 0)),
+      '',
+      '        case ' + op.MATCH_STRING + ':',       // MATCH_STRING s, a, f, ...
+                 indent10(generateCondition(
+                   'input.substr(peg$currPos, peg$consts[bc[ip + 1]].length) === peg$consts[bc[ip + 1]]',
+                   1
+                 )),
+      '',
+      '        case ' + op.MATCH_STRING_IC + ':',    // MATCH_STRING_IC s, a, f, ...
+                 indent10(generateCondition(
+                   'input.substr(peg$currPos, peg$consts[bc[ip + 1]].length).toLowerCase() === peg$consts[bc[ip + 1]]',
+                   1
+                 )),
+      '',
+      '        case ' + op.MATCH_REGEXP + ':',       // MATCH_REGEXP r, a, f, ...
+                 indent10(generateCondition(
+                   'peg$consts[bc[ip + 1]].test(input.charAt(peg$currPos))',
+                   1
+                 )),
+      '',
+      '        case ' + op.ACCEPT_N + ':',           // ACCEPT_N n
+      '          stack.push(input.substr(peg$currPos, bc[ip + 1]));',
+      '          peg$currPos += bc[ip + 1];',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.ACCEPT_STRING + ':',      // ACCEPT_STRING s
+      '          stack.push(peg$consts[bc[ip + 1]]);',
+      '          peg$currPos += peg$consts[bc[ip + 1]].length;',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.FAIL + ':',               // FAIL e
+      '          stack.push(peg$FAILED);',
+      '          if (peg$silentFails === 0) {',
+      '            peg$fail(peg$consts[bc[ip + 1]]);',
+      '          }',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.LOAD_SAVED_POS + ':',     // LOAD_SAVED_POS p
+      '          peg$savedPos = stack[stack.length - 1 - bc[ip + 1]];',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.UPDATE_SAVED_POS + ':',   // UPDATE_SAVED_POS
+      '          peg$savedPos = peg$currPos;',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.CALL + ':',               // CALL f, n, pc, p1, p2, ..., pN
+                 indent10(generateCall()),
+      '',
+      '        case ' + op.RULE + ':',               // RULE r
+      '          stack.push(peg$parseRule(bc[ip + 1]));',
+      '          ip += 2;',
+      '          break;',
+      '',
+      '        case ' + op.SILENT_FAILS_ON + ':',    // SILENT_FAILS_ON
+      '          peg$silentFails++;',
+      '          ip++;',
+      '          break;',
+      '',
+      '        case ' + op.SILENT_FAILS_OFF + ':',   // SILENT_FAILS_OFF
+      '          peg$silentFails--;',
+      '          ip++;',
+      '          break;',
+      '',
+      '        default:',
+      '          throw new Error("Invalid opcode: " + bc[ip] + ".");',
+      '      }',
+      '    }',
+      '',
+      '    if (ends.length > 0) {',
+      '      end = ends.pop();',
+      '      ip = ips.pop();',
+      '    } else {',
+      '      break;',
+      '    }',
+      '  }'
+    ].join('\n'));
+
+    parts.push(indent2(generateRuleFooter('peg$ruleNames[index]', 'stack[0]')));
+    parts.push('}');
+
+    return parts.join('\n');
+  }
+
+  function generateRuleFunction(rule) {
+    var parts = [], code;
+
+    function c(i) { return "peg$c" + i; } // |consts[i]| of the abstract machine
+    function s(i) { return "s"     + i; } // |stack[i]| of the abstract machine
+
+    var stack = {
+          sp:    -1,
+          maxSp: -1,
+
+          push: function(exprCode) {
+            var code = s(++this.sp) + ' = ' + exprCode + ';';
+
+            if (this.sp > this.maxSp) { this.maxSp = this.sp; }
+
+            return code;
+          },
+
+          pop: function() {
+            var n, values;
+
+            if (arguments.length === 0) {
+              return s(this.sp--);
+            } else {
+              n = arguments[0];
+              values = arrays.map(arrays.range(this.sp - n + 1, this.sp + 1), s);
+              this.sp -= n;
+
+              return values;
+            }
+          },
+
+          top: function() {
+            return s(this.sp);
+          },
+
+          index: function(i) {
+            return s(this.sp - i);
+          }
+        };
+
+    function compile(bc) {
+      var ip    = 0,
+          end   = bc.length,
+          parts = [],
+          value;
+
+      function compileCondition(cond, argCount) {
+        var baseLength = argCount + 3,
+            thenLength = bc[ip + baseLength - 2],
+            elseLength = bc[ip + baseLength - 1],
+            baseSp     = stack.sp,
+            thenCode, elseCode, thenSp, elseSp;
+
+        ip += baseLength;
+        thenCode = compile(bc.slice(ip, ip + thenLength));
+        thenSp = stack.sp;
+        ip += thenLength;
+
+        if (elseLength > 0) {
+          stack.sp = baseSp;
+          elseCode = compile(bc.slice(ip, ip + elseLength));
+          elseSp = stack.sp;
+          ip += elseLength;
+
+          if (thenSp !== elseSp) {
+            throw new Error(
+              "Branches of a condition must move the stack pointer in the same way."
+            );
+          }
+        }
+
+        parts.push('if (' + cond + ') {');
+        parts.push(indent2(thenCode));
+        if (elseLength > 0) {
+          parts.push('} else {');
+          parts.push(indent2(elseCode));
+        }
+        parts.push('}');
+      }
+
+      function compileLoop(cond) {
+        var baseLength = 2,
+            bodyLength = bc[ip + baseLength - 1],
+            baseSp     = stack.sp,
+            bodyCode, bodySp;
+
+        ip += baseLength;
+        bodyCode = compile(bc.slice(ip, ip + bodyLength));
+        bodySp = stack.sp;
+        ip += bodyLength;
+
+        if (bodySp !== baseSp) {
+          throw new Error("Body of a loop can't move the stack pointer.");
+        }
+
+        parts.push('while (' + cond + ') {');
+        parts.push(indent2(bodyCode));
+        parts.push('}');
+      }
+
+      function compileCall() {
+        var baseLength   = 4,
+            paramsLength = bc[ip + baseLength - 1];
+
+        var value = c(bc[ip + 1]) + '('
+              + arrays.map(
+                  bc.slice(ip + baseLength, ip + baseLength + paramsLength),
+                  function(p) { return stack.index(p); }
+                ).join(', ')
+              + ')';
+        stack.pop(bc[ip + 2]);
+        parts.push(stack.push(value));
+        ip += baseLength + paramsLength;
+      }
+
+      while (ip < end) {
+        switch (bc[ip]) {
+          case op.PUSH:               // PUSH c
+            parts.push(stack.push(c(bc[ip + 1])));
+            ip += 2;
+            break;
+
+          case op.PUSH_CURR_POS:      // PUSH_CURR_POS
+            parts.push(stack.push('peg$currPos'));
+            ip++;
+            break;
+
+          case op.PUSH_UNDEFINED:      // PUSH_UNDEFINED
+            parts.push(stack.push('void 0'));
+            ip++;
+            break;
+
+          case op.PUSH_NULL:          // PUSH_NULL
+            parts.push(stack.push('null'));
+            ip++;
+            break;
+
+          case op.PUSH_FAILED:        // PUSH_FAILED
+            parts.push(stack.push('peg$FAILED'));
+            ip++;
+            break;
+
+          case op.PUSH_EMPTY_ARRAY:   // PUSH_EMPTY_ARRAY
+            parts.push(stack.push('[]'));
+            ip++;
+            break;
+
+          case op.POP:                // POP
+            stack.pop();
+            ip++;
+            break;
+
+          case op.POP_CURR_POS:       // POP_CURR_POS
+            parts.push('peg$currPos = ' + stack.pop() + ';');
+            ip++;
+            break;
+
+          case op.POP_N:              // POP_N n
+            stack.pop(bc[ip + 1]);
+            ip += 2;
+            break;
+
+          case op.NIP:                // NIP
+            value = stack.pop();
+            stack.pop();
+            parts.push(stack.push(value));
+            ip++;
+            break;
+
+          case op.APPEND:             // APPEND
+            value = stack.pop();
+            parts.push(stack.top() + '.push(' + value + ');');
+            ip++;
+            break;
+
+          case op.WRAP:               // WRAP n
+            parts.push(
+              stack.push('[' + stack.pop(bc[ip + 1]).join(', ') + ']')
+            );
+            ip += 2;
+            break;
+
+          case op.TEXT:               // TEXT
+            parts.push(
+              stack.push('input.substring(' + stack.pop() + ', peg$currPos)')
+            );
+            ip++;
+            break;
+
+          case op.IF:                 // IF t, f
+            compileCondition(stack.top(), 0);
+            break;
+
+          case op.IF_ERROR:           // IF_ERROR t, f
+            compileCondition(stack.top() + ' === peg$FAILED', 0);
+            break;
+
+          case op.IF_NOT_ERROR:       // IF_NOT_ERROR t, f
+            compileCondition(stack.top() + ' !== peg$FAILED', 0);
+            break;
+
+          case op.WHILE_NOT_ERROR:    // WHILE_NOT_ERROR b
+            compileLoop(stack.top() + ' !== peg$FAILED', 0);
+            break;
+
+          case op.MATCH_ANY:          // MATCH_ANY a, f, ...
+            compileCondition('input.length > peg$currPos', 0);
+            break;
+
+          case op.MATCH_STRING:       // MATCH_STRING s, a, f, ...
+            compileCondition(
+              eval(ast.consts[bc[ip + 1]]).length > 1
+                ? 'input.substr(peg$currPos, '
+                    + eval(ast.consts[bc[ip + 1]]).length
+                    + ') === '
+                    + c(bc[ip + 1])
+                : 'input.charCodeAt(peg$currPos) === '
+                    + eval(ast.consts[bc[ip + 1]]).charCodeAt(0),
+              1
+            );
+            break;
+
+          case op.MATCH_STRING_IC:    // MATCH_STRING_IC s, a, f, ...
+            compileCondition(
+              'input.substr(peg$currPos, '
+                + eval(ast.consts[bc[ip + 1]]).length
+                + ').toLowerCase() === '
+                + c(bc[ip + 1]),
+              1
+            );
+            break;
+
+          case op.MATCH_REGEXP:       // MATCH_REGEXP r, a, f, ...
+            compileCondition(
+              c(bc[ip + 1]) + '.test(input.charAt(peg$currPos))',
+              1
+            );
+            break;
+
+          case op.ACCEPT_N:           // ACCEPT_N n
+            parts.push(stack.push(
+              bc[ip + 1] > 1
+                ? 'input.substr(peg$currPos, ' + bc[ip + 1] + ')'
+                : 'input.charAt(peg$currPos)'
+            ));
+            parts.push(
+              bc[ip + 1] > 1
+                ? 'peg$currPos += ' + bc[ip + 1] + ';'
+                : 'peg$currPos++;'
+            );
+            ip += 2;
+            break;
+
+          case op.ACCEPT_STRING:      // ACCEPT_STRING s
+            parts.push(stack.push(c(bc[ip + 1])));
+            parts.push(
+              eval(ast.consts[bc[ip + 1]]).length > 1
+                ? 'peg$currPos += ' + eval(ast.consts[bc[ip + 1]]).length + ';'
+                : 'peg$currPos++;'
+            );
+            ip += 2;
+            break;
+
+          case op.FAIL:               // FAIL e
+            parts.push(stack.push('peg$FAILED'));
+            parts.push('if (peg$silentFails === 0) { peg$fail(' + c(bc[ip + 1]) + '); }');
+            ip += 2;
+            break;
+
+          case op.LOAD_SAVED_POS:     // LOAD_SAVED_POS p
+            parts.push('peg$savedPos = ' + stack.index(bc[ip + 1]) + ';');
+            ip += 2;
+            break;
+
+          case op.UPDATE_SAVED_POS:   // UPDATE_SAVED_POS
+            parts.push('peg$savedPos = peg$currPos;');
+            ip++;
+            break;
+
+          case op.CALL:               // CALL f, n, pc, p1, p2, ..., pN
+            compileCall();
+            break;
+
+          case op.RULE:               // RULE r
+            parts.push(stack.push("peg$parse" + ast.rules[bc[ip + 1]].name + "()"));
+            ip += 2;
+            break;
+
+          case op.SILENT_FAILS_ON:    // SILENT_FAILS_ON
+            parts.push('peg$silentFails++;');
+            ip++;
+            break;
+
+          case op.SILENT_FAILS_OFF:   // SILENT_FAILS_OFF
+            parts.push('peg$silentFails--;');
+            ip++;
+            break;
+
+          default:
+            throw new Error("Invalid opcode: " + bc[ip] + ".");
+        }
+      }
+
+      return parts.join('\n');
+    }
+
+    code = compile(rule.bytecode);
+
+    parts.push('function peg$parse' + rule.name + '() {');
+
+    if (options.trace) {
+      parts.push([
+        '  var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ',',
+        '      startPos = peg$currPos;'
+      ].join('\n'));
+    } else {
+      parts.push(
+        '  var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ';'
+      );
+    }
+
+    parts.push(indent2(generateRuleHeader(
+      '"' + js.stringEscape(rule.name) + '"',
+      asts.indexOfRule(ast, rule.name)
+    )));
+    parts.push(indent2(code));
+    parts.push(indent2(generateRuleFooter(
+      '"' + js.stringEscape(rule.name) + '"',
+      s(0)
+    )));
+
+    parts.push('}');
+
+    return parts.join('\n');
+  }
+
+  var parts = [],
+      startRuleIndices,   startRuleIndex,
+      startRuleFunctions, startRuleFunction,
+      ruleNames;
+
+  parts.push([
+    '(function() {',
+    '  "use strict";',
+    '',
+    '  /*',
+    '   * Generated by PEG.js 0.9.0.',
+    '   *',
+    '   * http://pegjs.org/',
+    '   */',
+    '',
+    '  function peg$subclass(child, parent) {',
+    '    function ctor() { this.constructor = child; }',
+    '    ctor.prototype = parent.prototype;',
+    '    child.prototype = new ctor();',
+    '  }',
+    '',
+    '  function peg$SyntaxError(message, expected, found, location) {',
+    '    this.message  = message;',
+    '    this.expected = expected;',
+    '    this.found    = found;',
+    '    this.location = location;',
+    '    this.name     = "SyntaxError";',
+    '',
+    '    if (typeof Error.captureStackTrace === "function") {',
+    '      Error.captureStackTrace(this, peg$SyntaxError);',
+    '    }',
+    '  }',
+    '',
+    '  peg$subclass(peg$SyntaxError, Error);',
+    ''
+  ].join('\n'));
+
+  if (options.trace) {
+    parts.push([
+      '  function peg$DefaultTracer() {',
+      '    this.indentLevel = 0;',
+      '  }',
+      '',
+      '  peg$DefaultTracer.prototype.trace = function(event) {',
+      '    var that = this;',
+      '',
+      '    function log(event) {',
+      '      function repeat(string, n) {',
+      '         var result = "", i;',
+      '',
+      '         for (i = 0; i < n; i++) {',
+      '           result += string;',
+      '         }',
+      '',
+      '         return result;',
+      '      }',
+      '',
+      '      function pad(string, length) {',
+      '        return string + repeat(" ", length - string.length);',
+      '      }',
+      '',
+      '      if (typeof console === "object") {',   // IE 8-10
+      '        console.log(',
+      '          event.location.start.line + ":" + event.location.start.column + "-"',
+      '            + event.location.end.line + ":" + event.location.end.column + " "',
+      '            + pad(event.type, 10) + " "',
+      '            + repeat("  ", that.indentLevel) + event.rule',
+      '        );',
+      '      }',
+      '    }',
+      '',
+      '    switch (event.type) {',
+      '      case "rule.enter":',
+      '        log(event);',
+      '        this.indentLevel++;',
+      '        break;',
+      '',
+      '      case "rule.match":',
+      '        this.indentLevel--;',
+      '        log(event);',
+      '        break;',
+      '',
+      '      case "rule.fail":',
+      '        this.indentLevel--;',
+      '        log(event);',
+      '        break;',
+      '',
+      '      default:',
+      '        throw new Error("Invalid event type: " + event.type + ".");',
+      '    }',
+      '  };',
+      ''
+    ].join('\n'));
+  }
+
+  parts.push([
+    '  function peg$parse(input) {',
+    '    var options = arguments.length > 1 ? arguments[1] : {},',
+    '        parser  = this,',
+    '',
+    '        peg$FAILED = {},',
+    ''
+  ].join('\n'));
+
+  if (options.optimize === "size") {
+    startRuleIndices = '{ '
+                     + arrays.map(
+                         options.allowedStartRules,
+                         function(r) { return r + ': ' + asts.indexOfRule(ast, r); }
+                       ).join(', ')
+                     + ' }';
+    startRuleIndex = asts.indexOfRule(ast, options.allowedStartRules[0]);
+
+    parts.push([
+      '        peg$startRuleIndices = ' + startRuleIndices + ',',
+      '        peg$startRuleIndex   = ' + startRuleIndex + ','
+    ].join('\n'));
+  } else {
+    startRuleFunctions = '{ '
+                     + arrays.map(
+                         options.allowedStartRules,
+                         function(r) { return r + ': peg$parse' + r; }
+                       ).join(', ')
+                     + ' }';
+    startRuleFunction = 'peg$parse' + options.allowedStartRules[0];
+
+    parts.push([
+      '        peg$startRuleFunctions = ' + startRuleFunctions + ',',
+      '        peg$startRuleFunction  = ' + startRuleFunction + ','
+    ].join('\n'));
+  }
+
+  parts.push('');
+
+  parts.push(indent8(generateTables()));
+
+  parts.push([
+    '',
+    '        peg$currPos          = 0,',
+    '        peg$savedPos         = 0,',
+    '        peg$posDetailsCache  = [{ line: 1, column: 1, seenCR: false }],',
+    '        peg$maxFailPos       = 0,',
+    '        peg$maxFailExpected  = [],',
+    '        peg$silentFails      = 0,',   // 0 = report failures, > 0 = silence failures
+    ''
+  ].join('\n'));
+
+  if (options.cache) {
+    parts.push([
+      '        peg$resultsCache = {},',
+      ''
+    ].join('\n'));
+  }
+
+  if (options.trace) {
+    if (options.optimize === "size") {
+      ruleNames = '['
+                + arrays.map(
+                    ast.rules,
+                    function(r) { return '"' + js.stringEscape(r.name) + '"'; }
+                  ).join(', ')
+                + ']';
+
+      parts.push([
+        '        peg$ruleNames = ' + ruleNames + ',',
+        ''
+      ].join('\n'));
+    }
+
+    parts.push([
+      '        peg$tracer = "tracer" in options ? options.tracer : new peg$DefaultTracer(),',
+      ''
+    ].join('\n'));
+  }
+
+  parts.push([
+    '        peg$result;',
+    ''
+  ].join('\n'));
+
+  if (options.optimize === "size") {
+    parts.push([
+      '    if ("startRule" in options) {',
+      '      if (!(options.startRule in peg$startRuleIndices)) {',
+      '        throw new Error("Can\'t start parsing from rule \\"" + options.startRule + "\\".");',
+      '      }',
+      '',
+      '      peg$startRuleIndex = peg$startRuleIndices[options.startRule];',
+      '    }'
+    ].join('\n'));
+  } else {
+    parts.push([
+      '    if ("startRule" in options) {',
+      '      if (!(options.startRule in peg$startRuleFunctions)) {',
+      '        throw new Error("Can\'t start parsing from rule \\"" + options.startRule + "\\".");',
+      '      }',
+      '',
+      '      peg$startRuleFunction = peg$startRuleFunctions[options.startRule];',
+      '    }'
+    ].join('\n'));
+  }
+
+  parts.push([
+    '',
+    '    function text() {',
+    '      return input.substring(peg$savedPos, peg$currPos);',
+    '    }',
+    '',
+    '    function location() {',
+    '      return peg$computeLocation(peg$savedPos, peg$currPos);',
+    '    }',
+    '',
+    '    function expected(description) {',
+    '      throw peg$buildException(',
+    '        null,',
+    '        [{ type: "other", description: description }],',
+    '        input.substring(peg$savedPos, peg$currPos),',
+    '        peg$computeLocation(peg$savedPos, peg$currPos)',
+    '      );',
+    '    }',
+    '',
+    '    function error(message) {',
+    '      throw peg$buildException(',
+    '        message,',
+    '        null,',
+    '        input.substring(peg$savedPos, peg$currPos),',
+    '        peg$computeLocation(peg$savedPos, peg$currPos)',
+    '      );',
+    '    }',
+    '',
+    '    function peg$computePosDetails(pos) {',
+    '      var details = peg$posDetailsCache[pos],',
+    '          p, ch;',
+    '',
+    '      if (details) {',
+    '        return details;',
+    '      } else {',
+    '        p = pos - 1;',
+    '        while (!peg$posDetailsCache[p]) {',
+    '          p--;',
+    '        }',
+    '',
+    '        details = peg$posDetailsCache[p];',
+    '        details = {',
+    '          line:   details.line,',
+    '          column: details.column,',
+    '          seenCR: details.seenCR',
+    '        };',
+    '',
+    '        while (p < pos) {',
+    '          ch = input.charAt(p);',
+    '          if (ch === "\\n") {',
+    '            if (!details.seenCR) { details.line++; }',
+    '            details.column = 1;',
+    '            details.seenCR = false;',
+    '          } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {',
+    '            details.line++;',
+    '            details.column = 1;',
+    '            details.seenCR = true;',
+    '          } else {',
+    '            details.column++;',
+    '            details.seenCR = false;',
+    '          }',
+    '',
+    '          p++;',
+    '        }',
+    '',
+    '        peg$posDetailsCache[pos] = details;',
+    '        return details;',
+    '      }',
+    '    }',
+    '',
+    '    function peg$computeLocation(startPos, endPos) {',
+    '      var startPosDetails = peg$computePosDetails(startPos),',
+    '          endPosDetails   = peg$computePosDetails(endPos);',
+    '',
+    '      return {',
+    '        start: {',
+    '          offset: startPos,',
+    '          line:   startPosDetails.line,',
+    '          column: startPosDetails.column',
+    '        },',
+    '        end: {',
+    '          offset: endPos,',
+    '          line:   endPosDetails.line,',
+    '          column: endPosDetails.column',
+    '        }',
+    '      };',
+    '    }',
+    '',
+    '    function peg$fail(expected) {',
+    '      if (peg$currPos < peg$maxFailPos) { return; }',
+    '',
+    '      if (peg$currPos > peg$maxFailPos) {',
+    '        peg$maxFailPos = peg$currPos;',
+    '        peg$maxFailExpected = [];',
+    '      }',
+    '',
+    '      peg$maxFailExpected.push(expected);',
+    '    }',
+    '',
+    '    function peg$buildException(message, expected, found, location) {',
+    '      function cleanupExpected(expected) {',
+    '        var i = 1;',
+    '',
+    '        expected.sort(function(a, b) {',
+    '          if (a.description < b.description) {',
+    '            return -1;',
+    '          } else if (a.description > b.description) {',
+    '            return 1;',
+    '          } else {',
+    '            return 0;',
+    '          }',
+    '        });',
+    '',
+    /*
+     * This works because the bytecode generator guarantees that every
+     * expectation object exists only once, so it's enough to use |===| instead
+     * of deeper structural comparison.
+     */
+    '        while (i < expected.length) {',
+    '          if (expected[i - 1] === expected[i]) {',
+    '            expected.splice(i, 1);',
+    '          } else {',
+    '            i++;',
+    '          }',
+    '        }',
+    '      }',
+    '',
+    '      function buildMessage(expected, found) {',
+    '        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 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(/[\\u0100-\\u0FFF]/g,         function(ch) { return \'\\\\u0\' + hex(ch); })',
+    '            .replace(/[\\u1000-\\uFFFF]/g,         function(ch) { return \'\\\\u\'  + hex(ch); });',
+    '        }',
+    '',
+    '        var expectedDescs = new Array(expected.length),',
+    '            expectedDesc, foundDesc, i;',
+    '',
+    '        for (i = 0; i < expected.length; i++) {',
+    '          expectedDescs[i] = expected[i].description;',
+    '        }',
+    '',
+    '        expectedDesc = expected.length > 1',
+    '          ? expectedDescs.slice(0, -1).join(", ")',
+    '              + " or "',
+    '              + expectedDescs[expected.length - 1]',
+    '          : expectedDescs[0];',
+    '',
+    '        foundDesc = found ? "\\"" + stringEscape(found) + "\\"" : "end of input";',
+    '',
+    '        return "Expected " + expectedDesc + " but " + foundDesc + " found.";',
+    '      }',
+    '',
+    '      if (expected !== null) {',
+    '        cleanupExpected(expected);',
+    '      }',
+    '',
+    '      return new peg$SyntaxError(',
+    '        message !== null ? message : buildMessage(expected, found),',
+    '        expected,',
+    '        found,',
+    '        location',
+    '      );',
+    '    }',
+    ''
+  ].join('\n'));
+
+  if (options.optimize === "size") {
+    parts.push(indent4(generateInterpreter()));
+    parts.push('');
+  } else {
+    arrays.each(ast.rules, function(rule) {
+      parts.push(indent4(generateRuleFunction(rule)));
+      parts.push('');
+    });
+  }
+
+  if (ast.initializer) {
+    parts.push(indent4(ast.initializer.code));
+    parts.push('');
+  }
+
+  if (options.optimize === "size") {
+    parts.push('    peg$result = peg$parseRule(peg$startRuleIndex);');
+  } else {
+    parts.push('    peg$result = peg$startRuleFunction();');
+  }
+
+  parts.push([
+    '',
+    '    if (peg$result !== peg$FAILED && peg$currPos === input.length) {',
+    '      return peg$result;',
+    '    } else {',
+    '      if (peg$result !== peg$FAILED && peg$currPos < input.length) {',
+    '        peg$fail({ type: "end", description: "end of input" });',
+    '      }',
+    '',
+    '      throw peg$buildException(',
+    '        null,',
+    '        peg$maxFailExpected,',
+    '        peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,',
+    '        peg$maxFailPos < input.length',
+    '          ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)',
+    '          : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)',
+    '      );',
+    '    }',
+    '  }',
+    '',
+    '  return {'
+  ].join('\n'));
+
+  if (options.trace) {
+    parts.push([
+      '    SyntaxError:   peg$SyntaxError,',
+      '    DefaultTracer: peg$DefaultTracer,',
+      '    parse:         peg$parse'
+    ].join('\n'));
+  } else {
+    parts.push([
+      '    SyntaxError: peg$SyntaxError,',
+      '    parse:       peg$parse'
+    ].join('\n'));
+  }
+
+  parts.push([
+    '  };',
+    '})()'
+  ].join('\n'));
+
+  ast.code = parts.join('\n');
+}
+
+module.exports = generateJavascript;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js b/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js
new file mode 100644
index 0000000..8d50548
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js
@@ -0,0 +1,42 @@
+"use strict";
+
+var arrays  = require("../../utils/arrays"),
+    visitor = require("../visitor");
+
+/*
+ * Removes proxy rules -- that is, rules that only delegate to other rule.
+ */
+function removeProxyRules(ast, options) {
+  function isProxyRule(node) {
+    return node.type === "rule" && node.expression.type === "rule_ref";
+  }
+
+  function replaceRuleRefs(ast, from, to) {
+    var replace = visitor.build({
+      rule_ref: function(node) {
+        if (node.name === from) {
+          node.name = to;
+        }
+      }
+    });
+
+    replace(ast);
+  }
+
+  var indices = [];
+
+  arrays.each(ast.rules, function(rule, i) {
+    if (isProxyRule(rule)) {
+      replaceRuleRefs(ast, rule.name, rule.expression.name);
+      if (!arrays.contains(options.allowedStartRules, rule.name)) {
+        indices.push(i);
+      }
+    }
+  });
+
+  indices.reverse();
+
+  arrays.each(indices, function(i) { ast.rules.splice(i, 1); });
+}
+
+module.exports = removeProxyRules;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/passes/report-infinite-loops.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/passes/report-infinite-loops.js b/node_modules/pegjs/lib/compiler/passes/report-infinite-loops.js
new file mode 100644
index 0000000..7d23936
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/passes/report-infinite-loops.js
@@ -0,0 +1,29 @@
+"use strict";
+
+var GrammarError = require("../../grammar-error"),
+    asts         = require("../asts"),
+    visitor      = require("../visitor");
+
+/*
+ * Reports expressions that don't consume any input inside |*| or |+| in the
+ * grammar, which prevents infinite loops in the generated parser.
+ */
+function reportInfiniteLoops(ast) {
+  var check = visitor.build({
+    zero_or_more: function(node) {
+      if (!asts.alwaysAdvancesOnSuccess(ast, node.expression)) {
+        throw new GrammarError("Infinite loop detected.", node.location);
+      }
+    },
+
+    one_or_more: function(node) {
+      if (!asts.alwaysAdvancesOnSuccess(ast, node.expression)) {
+        throw new GrammarError("Infinite loop detected.", node.location);
+      }
+    }
+  });
+
+  check(ast);
+}
+
+module.exports = reportInfiniteLoops;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/passes/report-left-recursion.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/passes/report-left-recursion.js b/node_modules/pegjs/lib/compiler/passes/report-left-recursion.js
new file mode 100644
index 0000000..9745fce
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/passes/report-left-recursion.js
@@ -0,0 +1,53 @@
+"use strict";
+
+var arrays       = require("../../utils/arrays"),
+    GrammarError = require("../../grammar-error"),
+    asts         = require("../asts"),
+    visitor      = require("../visitor");
+
+/*
+ * Reports left recursion in the grammar, which prevents infinite recursion in
+ * the generated parser.
+ *
+ * Both direct and indirect recursion is detected. The pass also correctly
+ * reports cases like this:
+ *
+ *   start = "a"? start
+ *
+ * In general, if a rule reference can be reached without consuming any input,
+ * it can lead to left recursion.
+ */
+function reportLeftRecursion(ast) {
+  var visitedRules = [];
+
+  var check = visitor.build({
+    rule: function(node) {
+      visitedRules.push(node.name);
+      check(node.expression);
+      visitedRules.pop(node.name);
+    },
+
+    sequence: function(node) {
+      arrays.every(node.elements, function(element) {
+        check(element);
+
+        return !asts.alwaysAdvancesOnSuccess(ast, element);
+      });
+    },
+
+    rule_ref: function(node) {
+      if (arrays.contains(visitedRules, node.name)) {
+        throw new GrammarError(
+          "Left recursion detected for rule \"" + node.name + "\".",
+          node.location
+        );
+      }
+
+      check(asts.findRule(ast, node.name));
+    }
+  });
+
+  check(ast);
+}
+
+module.exports = reportLeftRecursion;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/passes/report-missing-rules.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/passes/report-missing-rules.js b/node_modules/pegjs/lib/compiler/passes/report-missing-rules.js
new file mode 100644
index 0000000..476d84e
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/passes/report-missing-rules.js
@@ -0,0 +1,23 @@
+"use strict";
+
+var GrammarError = require("../../grammar-error"),
+    asts         = require("../asts"),
+    visitor      = require("../visitor");
+
+/* Checks that all referenced rules exist. */
+function reportMissingRules(ast) {
+  var check = visitor.build({
+    rule_ref: function(node) {
+      if (!asts.findRule(ast, node.name)) {
+        throw new GrammarError(
+          "Referenced rule \"" + node.name + "\" does not exist.",
+          node.location
+        );
+      }
+    }
+  });
+
+  check(ast);
+}
+
+module.exports = reportMissingRules;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/compiler/visitor.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/compiler/visitor.js b/node_modules/pegjs/lib/compiler/visitor.js
new file mode 100644
index 0000000..70e6f12
--- /dev/null
+++ b/node_modules/pegjs/lib/compiler/visitor.js
@@ -0,0 +1,71 @@
+"use strict";
+
+var objects = require("../utils/objects"),
+    arrays  = require("../utils/arrays");
+
+/* Simple AST node visitor builder. */
+var visitor = {
+  build: function(functions) {
+    function visit(node) {
+      return functions[node.type].apply(null, arguments);
+    }
+
+    function visitNop() { }
+
+    function visitExpression(node) {
+      var extraArgs = Array.prototype.slice.call(arguments, 1);
+
+      visit.apply(null, [node.expression].concat(extraArgs));
+    }
+
+    function visitChildren(property) {
+      return function(node) {
+        var extraArgs = Array.prototype.slice.call(arguments, 1);
+
+        arrays.each(node[property], function(child) {
+          visit.apply(null, [child].concat(extraArgs));
+        });
+      };
+    }
+
+    var DEFAULT_FUNCTIONS = {
+          grammar: function(node) {
+            var extraArgs = Array.prototype.slice.call(arguments, 1);
+
+            if (node.initializer) {
+              visit.apply(null, [node.initializer].concat(extraArgs));
+            }
+
+            arrays.each(node.rules, function(rule) {
+              visit.apply(null, [rule].concat(extraArgs));
+            });
+          },
+
+          initializer:  visitNop,
+          rule:         visitExpression,
+          named:        visitExpression,
+          choice:       visitChildren("alternatives"),
+          action:       visitExpression,
+          sequence:     visitChildren("elements"),
+          labeled:      visitExpression,
+          text:         visitExpression,
+          simple_and:   visitExpression,
+          simple_not:   visitExpression,
+          optional:     visitExpression,
+          zero_or_more: visitExpression,
+          one_or_more:  visitExpression,
+          semantic_and: visitNop,
+          semantic_not: visitNop,
+          rule_ref:     visitNop,
+          literal:      visitNop,
+          "class":      visitNop,
+          any:          visitNop
+        };
+
+    objects.defaults(functions, DEFAULT_FUNCTIONS);
+
+    return visit;
+  }
+};
+
+module.exports = visitor;

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/0d465c30/node_modules/pegjs/lib/grammar-error.js
----------------------------------------------------------------------
diff --git a/node_modules/pegjs/lib/grammar-error.js b/node_modules/pegjs/lib/grammar-error.js
new file mode 100644
index 0000000..758b8e9
--- /dev/null
+++ b/node_modules/pegjs/lib/grammar-error.js
@@ -0,0 +1,18 @@
+"use strict";
+
+var classes = require("./utils/classes");
+
+/* Thrown when the grammar contains an error. */
+function GrammarError(message, location) {
+  this.name = "GrammarError";
+  this.message = message;
+  this.location = location;
+
+  if (typeof Error.captureStackTrace === "function") {
+    Error.captureStackTrace(this, GrammarError);
+  }
+}
+
+classes.subclass(GrammarError, Error);
+
+module.exports = GrammarError;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message