You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2016/06/17 06:17:20 UTC
[09/32] ios commit: CB-11445 Updated checked-in node_modules
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