aboutsummaryrefslogtreecommitdiff
path: root/cordova/node_modules/pegjs/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'cordova/node_modules/pegjs/lib/compiler')
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/asts.js65
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/index.js73
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/js.js58
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/opcodes.js54
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js631
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/generate-js.js1394
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js42
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-labels.js54
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-rules.js28
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-recursion.js57
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-repetition.js35
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/passes/report-undefined-rules.js23
-rw-r--r--cordova/node_modules/pegjs/lib/compiler/visitor.js72
13 files changed, 2586 insertions, 0 deletions
diff --git a/cordova/node_modules/pegjs/lib/compiler/asts.js b/cordova/node_modules/pegjs/lib/compiler/asts.js
new file mode 100644
index 0000000..7dac649
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/asts.js
@@ -0,0 +1,65 @@
+"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; });
+ },
+
+ alwaysConsumesOnSuccess: function(ast, node) {
+ function consumesTrue() { return true; }
+ function consumesFalse() { return false; }
+
+ function consumesExpression(node) {
+ return consumes(node.expression);
+ }
+
+ var consumes = visitor.build({
+ rule: consumesExpression,
+ named: consumesExpression,
+
+ choice: function(node) {
+ return arrays.every(node.alternatives, consumes);
+ },
+
+ action: consumesExpression,
+
+ sequence: function(node) {
+ return arrays.some(node.elements, consumes);
+ },
+
+ labeled: consumesExpression,
+ text: consumesExpression,
+ simple_and: consumesFalse,
+ simple_not: consumesFalse,
+ optional: consumesFalse,
+ zero_or_more: consumesFalse,
+ one_or_more: consumesExpression,
+ group: consumesExpression,
+ semantic_and: consumesFalse,
+ semantic_not: consumesFalse,
+
+ rule_ref: function(node) {
+ return consumes(asts.findRule(ast, node.name));
+ },
+
+ literal: function(node) {
+ return node.value !== "";
+ },
+
+ "class": consumesTrue,
+ any: consumesTrue
+ });
+
+ return consumes(node);
+ }
+};
+
+module.exports = asts;
diff --git a/cordova/node_modules/pegjs/lib/compiler/index.js b/cordova/node_modules/pegjs/lib/compiler/index.js
new file mode 100644
index 0000000..1248598
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/index.js
@@ -0,0 +1,73 @@
+"use strict";
+
+var arrays = require("../utils/arrays"),
+ objects = require("../utils/objects");
+
+var compiler = {
+ /*
+ * AST node visitor builder. Useful mainly for plugins which manipulate the
+ * AST.
+ */
+ visitor: require("./visitor"),
+
+ /*
+ * 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: {
+ reportUndefinedRules: require("./passes/report-undefined-rules"),
+ reportDuplicateRules: require("./passes/report-duplicate-rules"),
+ reportDuplicateLabels: require("./passes/report-duplicate-labels"),
+ reportInfiniteRecursion: require("./passes/report-infinite-recursion"),
+ reportInfiniteRepetition: require("./passes/report-infinite-repetition")
+ },
+ transform: {
+ removeProxyRules: require("./passes/remove-proxy-rules")
+ },
+ generate: {
+ generateBytecode: require("./passes/generate-bytecode"),
+ generateJS: require("./passes/generate-js")
+ }
+ },
+
+ /*
+ * 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, options) {
+ options = options !== void 0 ? options : {};
+
+ var stage;
+
+ options = objects.clone(options);
+ objects.defaults(options, {
+ allowedStartRules: [ast.rules[0].name],
+ cache: false,
+ dependencies: {},
+ exportVar: null,
+ format: "bare",
+ optimize: "speed",
+ output: "parser",
+ trace: false
+ });
+
+ 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;
diff --git a/cordova/node_modules/pegjs/lib/compiler/js.js b/cordova/node_modules/pegjs/lib/compiler/js.js
new file mode 100644
index 0000000..3da25a4
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/js.js
@@ -0,0 +1,58 @@
+"use strict";
+
+function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
+
+/* JavaScript code generation helpers. */
+var js = {
+ 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 the "\v" escape sequence is not used because IE does not like
+ * it.
+ */
+ return s
+ .replace(/\\/g, '\\\\') // backslash
+ .replace(/"/g, '\\"') // closing double quote
+ .replace(/\0/g, '\\0') // null
+ .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-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
+ .replace(/[\x10-\x1F\x7F-\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-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
+ .replace(/[\x10-\x1F\x7F-\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 = js;
diff --git a/cordova/node_modules/pegjs/lib/compiler/opcodes.js b/cordova/node_modules/pegjs/lib/compiler/opcodes.js
new file mode 100644
index 0000000..4c52008
--- /dev/null
+++ b/cordova/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;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js b/cordova/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js
new file mode 100644
index 0000000..60c81a9
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/generate-bytecode.js
@@ -0,0 +1,631 @@
+"use strict";
+
+var arrays = require("../../utils/arrays"),
+ objects = require("../../utils/objects"),
+ asts = require("../asts"),
+ visitor = require("../visitor"),
+ op = require("../opcodes"),
+ js = require("../js");
+
+/* 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(
+ 'peg$otherExpectation("' + 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])
+ )
+ );
+ },
+
+ group: function(node, context) {
+ return generate(node.expression, {
+ sp: context.sp,
+ env: objects.clone(context.env),
+ action: null
+ });
+ },
+
+ 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(
+ 'peg$literalExpectation('
+ + '"' + js.stringEscape(node.value) + '", '
+ + node.ignoreCase
+ + ')'
+ );
+
+ /*
+ * 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, parts, 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 equivalents it can handle.
+ */
+ regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/';
+ }
+
+ parts = '['
+ + arrays.map(node.parts, function(part) {
+ return part instanceof Array
+ ? '["' + js.stringEscape(part[0]) + '", "' + js.stringEscape(part[1]) + '"]'
+ : '"' + js.stringEscape(part) + '"';
+ }).join(', ')
+ + ']';
+
+ regexpIndex = addConst(regexp);
+ expectedIndex = addConst(
+ 'peg$classExpectation('
+ + parts + ', '
+ + node.inverted + ', '
+ + node.ignoreCase
+ + ')'
+ );
+
+ return buildCondition(
+ [op.MATCH_REGEXP, regexpIndex],
+ [op.ACCEPT_N, 1],
+ [op.FAIL, expectedIndex]
+ );
+ },
+
+ any: function() {
+ var expectedIndex = addConst('peg$anyExpectation()');
+
+ return buildCondition(
+ [op.MATCH_ANY],
+ [op.ACCEPT_N, 1],
+ [op.FAIL, expectedIndex]
+ );
+ }
+ });
+
+ generate(ast);
+}
+
+module.exports = generateBytecode;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/generate-js.js b/cordova/node_modules/pegjs/lib/compiler/passes/generate-js.js
new file mode 100644
index 0000000..c579ac9
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/generate-js.js
@@ -0,0 +1,1394 @@
+"use strict";
+
+var arrays = require("../../utils/arrays"),
+ objects = require("../../utils/objects"),
+ asts = require("../asts"),
+ op = require("../opcodes"),
+ js = require("../js");
+
+/* Generates parser JavaScript code. */
+function generateJS(ast, options) {
+ /* These only indent non-empty lines to avoid trailing whitespace. */
+ function indent2(code) { return code.replace(/^(.+)$/gm, ' $1'); }
+ function indent6(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(n) {
+ var values;
+
+ if (n === void 0) {
+ return s(this.sp--);
+ } else {
+ 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');
+ }
+
+ function generateToplevel() {
+ var parts = [],
+ startRuleIndices, startRuleIndex,
+ startRuleFunctions, startRuleFunction,
+ ruleNames;
+
+ parts.push([
+ '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);',
+ '',
+ 'peg$SyntaxError.buildMessage = function(expected, found) {',
+ ' var DESCRIBE_EXPECTATION_FNS = {',
+ ' literal: function(expectation) {',
+ ' return "\\\"" + literalEscape(expectation.text) + "\\\"";',
+ ' },',
+ '',
+ ' "class": function(expectation) {',
+ ' var escapedParts = "",',
+ ' i;',
+ '',
+ ' for (i = 0; i < expectation.parts.length; i++) {',
+ ' escapedParts += expectation.parts[i] instanceof Array',
+ ' ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])',
+ ' : classEscape(expectation.parts[i]);',
+ ' }',
+ '',
+ ' return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";',
+ ' },',
+ '',
+ ' any: function(expectation) {',
+ ' return "any character";',
+ ' },',
+ '',
+ ' end: function(expectation) {',
+ ' return "end of input";',
+ ' },',
+ '',
+ ' other: function(expectation) {',
+ ' return expectation.description;',
+ ' }',
+ ' };',
+ '',
+ ' function hex(ch) {',
+ ' return ch.charCodeAt(0).toString(16).toUpperCase();',
+ ' }',
+ '',
+ ' function literalEscape(s) {',
+ ' return s',
+ ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
+ ' .replace(/"/g, \'\\\\"\')', // closing double quote
+ ' .replace(/\\0/g, \'\\\\0\')', // null
+ ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab
+ ' .replace(/\\n/g, \'\\\\n\')', // line feed
+ ' .replace(/\\r/g, \'\\\\r\')', // carriage return
+ ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
+ ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });',
+ ' }',
+ '',
+ ' function classEscape(s) {',
+ ' return s',
+ ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
+ ' .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(/\\r/g, \'\\\\r\')', // carriage return
+ ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
+ ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });',
+ ' }',
+ '',
+ ' function describeExpectation(expectation) {',
+ ' return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);',
+ ' }',
+ '',
+ ' function describeExpected(expected) {',
+ ' var descriptions = new Array(expected.length),',
+ ' i, j;',
+ '',
+ ' for (i = 0; i < expected.length; i++) {',
+ ' descriptions[i] = describeExpectation(expected[i]);',
+ ' }',
+ '',
+ ' descriptions.sort();',
+ '',
+ ' if (descriptions.length > 0) {',
+ ' for (i = 1, j = 1; i < descriptions.length; i++) {',
+ ' if (descriptions[i - 1] !== descriptions[i]) {',
+ ' descriptions[j] = descriptions[i];',
+ ' j++;',
+ ' }',
+ ' }',
+ ' descriptions.length = j;',
+ ' }',
+ '',
+ ' switch (descriptions.length) {',
+ ' case 1:',
+ ' return descriptions[0];',
+ '',
+ ' case 2:',
+ ' return descriptions[0] + " or " + descriptions[1];',
+ '',
+ ' default:',
+ ' return descriptions.slice(0, -1).join(", ")',
+ ' + ", or "',
+ ' + descriptions[descriptions.length - 1];',
+ ' }',
+ ' }',
+ '',
+ ' function describeFound(found) {',
+ ' return found ? "\\"" + literalEscape(found) + "\\"" : "end of input";',
+ ' }',
+ '',
+ ' return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";',
+ '};',
+ ''
+ ].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, options) {',
+ ' options = options !== void 0 ? options : {};',
+ '',
+ ' var 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(indent6(generateTables()));
+
+ parts.push([
+ '',
+ ' peg$currPos = 0,',
+ ' peg$savedPos = 0,',
+ ' peg$posDetailsCache = [{ line: 1, column: 1 }],',
+ ' 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, location) {',
+ ' location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)',
+ '',
+ ' throw peg$buildStructuredError(',
+ ' [peg$otherExpectation(description)],',
+ ' input.substring(peg$savedPos, peg$currPos),',
+ ' location',
+ ' );',
+ ' }',
+ '',
+ ' function error(message, location) {',
+ ' location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)',
+ '',
+ ' throw peg$buildSimpleError(message, location);',
+ ' }',
+ '',
+ ' function peg$literalExpectation(text, ignoreCase) {',
+ ' return { type: "literal", text: text, ignoreCase: ignoreCase };',
+ ' }',
+ '',
+ ' function peg$classExpectation(parts, inverted, ignoreCase) {',
+ ' return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };',
+ ' }',
+ '',
+ ' function peg$anyExpectation() {',
+ ' return { type: "any" };',
+ ' }',
+ '',
+ ' function peg$endExpectation() {',
+ ' return { type: "end" };',
+ ' }',
+ '',
+ ' function peg$otherExpectation(description) {',
+ ' return { type: "other", description: description };',
+ ' }',
+ '',
+ ' function peg$computePosDetails(pos) {',
+ ' var details = peg$posDetailsCache[pos], p;',
+ '',
+ ' if (details) {',
+ ' return details;',
+ ' } else {',
+ ' p = pos - 1;',
+ ' while (!peg$posDetailsCache[p]) {',
+ ' p--;',
+ ' }',
+ '',
+ ' details = peg$posDetailsCache[p];',
+ ' details = {',
+ ' line: details.line,',
+ ' column: details.column',
+ ' };',
+ '',
+ ' while (p < pos) {',
+ ' if (input.charCodeAt(p) === 10) {',
+ ' details.line++;',
+ ' details.column = 1;',
+ ' } else {',
+ ' details.column++;',
+ ' }',
+ '',
+ ' 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$buildSimpleError(message, location) {',
+ ' return new peg$SyntaxError(message, null, null, location);',
+ ' }',
+ '',
+ ' function peg$buildStructuredError(expected, found, location) {',
+ ' return new peg$SyntaxError(',
+ ' peg$SyntaxError.buildMessage(expected, found),',
+ ' expected,',
+ ' found,',
+ ' location',
+ ' );',
+ ' }',
+ ''
+ ].join('\n'));
+
+ if (options.optimize === "size") {
+ parts.push(indent2(generateInterpreter()));
+ parts.push('');
+ } else {
+ arrays.each(ast.rules, function(rule) {
+ parts.push(indent2(generateRuleFunction(rule)));
+ parts.push('');
+ });
+ }
+
+ if (ast.initializer) {
+ parts.push(indent2(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(peg$endExpectation());',
+ ' }',
+ '',
+ ' throw peg$buildStructuredError(',
+ ' 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)',
+ ' );',
+ ' }',
+ '}'
+ ].join('\n'));
+
+ return parts.join('\n');
+ }
+
+ function generateWrapper(toplevelCode) {
+ function generateGeneratedByComment() {
+ return [
+ '/*',
+ ' * Generated by PEG.js 0.10.0.',
+ ' *',
+ ' * http://pegjs.org/',
+ ' */'
+ ].join('\n');
+ }
+
+ function generateParserObject() {
+ return options.trace
+ ? [
+ '{',
+ ' SyntaxError: peg$SyntaxError,',
+ ' DefaultTracer: peg$DefaultTracer,',
+ ' parse: peg$parse',
+ '}'
+ ].join('\n')
+ : [
+ '{',
+ ' SyntaxError: peg$SyntaxError,',
+ ' parse: peg$parse',
+ '}'
+ ].join('\n');
+ }
+
+ var generators = {
+ bare: function() {
+ return [
+ generateGeneratedByComment(),
+ '(function() {',
+ ' "use strict";',
+ '',
+ indent2(toplevelCode),
+ '',
+ indent2('return ' + generateParserObject() + ';'),
+ '})()'
+ ].join('\n');
+ },
+
+ commonjs: function() {
+ var parts = [],
+ dependencyVars = objects.keys(options.dependencies),
+ requires = arrays.map(
+ dependencyVars,
+ function(variable) {
+ return variable
+ + ' = require("'
+ + js.stringEscape(options.dependencies[variable])
+ + '")';
+ }
+ );
+
+ parts.push([
+ generateGeneratedByComment(),
+ '',
+ '"use strict";',
+ ''
+ ].join('\n'));
+
+ if (requires.length > 0) {
+ parts.push('var ' + requires.join(', ') + ';');
+ parts.push('');
+ }
+
+ parts.push([
+ toplevelCode,
+ '',
+ 'module.exports = ' + generateParserObject() + ';',
+ ''
+ ].join('\n'));
+
+ return parts.join('\n');
+ },
+
+ amd: function() {
+ var dependencyIds = objects.values(options.dependencies),
+ dependencyVars = objects.keys(options.dependencies),
+ dependencies = '['
+ + arrays.map(
+ dependencyIds,
+ function(id) { return '"' + js.stringEscape(id) + '"'; }
+ ).join(', ')
+ + ']',
+ params = dependencyVars.join(', ');
+
+ return [
+ generateGeneratedByComment(),
+ 'define(' + dependencies + ', function(' + params + ') {',
+ ' "use strict";',
+ '',
+ indent2(toplevelCode),
+ '',
+ indent2('return ' + generateParserObject() + ';'),
+ '});',
+ ''
+ ].join('\n');
+ },
+
+ globals: function() {
+ return [
+ generateGeneratedByComment(),
+ '(function(root) {',
+ ' "use strict";',
+ '',
+ indent2(toplevelCode),
+ '',
+ indent2('root.' + options.exportVar + ' = ' + generateParserObject() + ';'),
+ '})(this);',
+ ''
+ ].join('\n');
+ },
+
+ umd: function() {
+ var parts = [],
+ dependencyIds = objects.values(options.dependencies),
+ dependencyVars = objects.keys(options.dependencies),
+ dependencies = '['
+ + arrays.map(
+ dependencyIds,
+ function(id) { return '"' + js.stringEscape(id) + '"'; }
+ ).join(', ')
+ + ']',
+ requires = arrays.map(
+ dependencyIds,
+ function(id) { return 'require("' + js.stringEscape(id) + '")'; }
+ ).join(', '),
+ params = dependencyVars.join(', ');
+
+ parts.push([
+ generateGeneratedByComment(),
+ '(function(root, factory) {',
+ ' if (typeof define === "function" && define.amd) {',
+ ' define(' + dependencies + ', factory);',
+ ' } else if (typeof module === "object" && module.exports) {',
+ ' module.exports = factory(' + requires + ');'
+ ].join('\n'));
+
+ if (options.exportVar !== null) {
+ parts.push([
+ ' } else {',
+ ' root.' + options.exportVar + ' = factory();'
+ ].join('\n'));
+ }
+
+ parts.push([
+ ' }',
+ '})(this, function(' + params + ') {',
+ ' "use strict";',
+ '',
+ indent2(toplevelCode),
+ '',
+ indent2('return ' + generateParserObject() + ';'),
+ '});',
+ ''
+ ].join('\n'));
+
+ return parts.join('\n');
+ }
+ };
+
+ return generators[options.format]();
+ }
+
+ ast.code = generateWrapper(generateToplevel());
+}
+
+module.exports = generateJS;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js b/cordova/node_modules/pegjs/lib/compiler/passes/remove-proxy-rules.js
new file mode 100644
index 0000000..8d50548
--- /dev/null
+++ b/cordova/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;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-labels.js b/cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-labels.js
new file mode 100644
index 0000000..16a0c11
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-labels.js
@@ -0,0 +1,54 @@
+"use strict";
+
+var GrammarError = require("../../grammar-error"),
+ arrays = require("../../utils/arrays"),
+ objects = require("../../utils/objects"),
+ visitor = require("../visitor");
+
+/* Checks that each label is defined only once within each scope. */
+function reportDuplicateLabels(ast) {
+ function checkExpressionWithClonedEnv(node, env) {
+ check(node.expression, objects.clone(env));
+ }
+
+ var check = visitor.build({
+ rule: function(node) {
+ check(node.expression, { });
+ },
+
+ choice: function(node, env) {
+ arrays.each(node.alternatives, function(alternative) {
+ check(alternative, objects.clone(env));
+ });
+ },
+
+ action: checkExpressionWithClonedEnv,
+
+ labeled: function(node, env) {
+ if (env.hasOwnProperty(node.label)) {
+ throw new GrammarError(
+ "Label \"" + node.label + "\" is already defined "
+ + "at line " + env[node.label].start.line + ", "
+ + "column " + env[node.label].start.column + ".",
+ node.location
+ );
+ }
+
+ check(node.expression, env);
+
+ env[node.label] = node.location;
+ },
+
+ text: checkExpressionWithClonedEnv,
+ simple_and: checkExpressionWithClonedEnv,
+ simple_not: checkExpressionWithClonedEnv,
+ optional: checkExpressionWithClonedEnv,
+ zero_or_more: checkExpressionWithClonedEnv,
+ one_or_more: checkExpressionWithClonedEnv,
+ group: checkExpressionWithClonedEnv
+ });
+
+ check(ast);
+}
+
+module.exports = reportDuplicateLabels;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-rules.js b/cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-rules.js
new file mode 100644
index 0000000..c621d37
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/report-duplicate-rules.js
@@ -0,0 +1,28 @@
+"use strict";
+
+var GrammarError = require("../../grammar-error"),
+ visitor = require("../visitor");
+
+/* Checks that each rule is defined only once. */
+function reportDuplicateRules(ast) {
+ var rules = {};
+
+ var check = visitor.build({
+ rule: function(node) {
+ if (rules.hasOwnProperty(node.name)) {
+ throw new GrammarError(
+ "Rule \"" + node.name + "\" is already defined "
+ + "at line " + rules[node.name].start.line + ", "
+ + "column " + rules[node.name].start.column + ".",
+ node.location
+ );
+ }
+
+ rules[node.name] = node.location;
+ }
+ });
+
+ check(ast);
+}
+
+module.exports = reportDuplicateRules;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-recursion.js b/cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-recursion.js
new file mode 100644
index 0000000..1230a2f
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-recursion.js
@@ -0,0 +1,57 @@
+"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 reportInfiniteRecursion(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.alwaysConsumesOnSuccess(ast, element);
+ });
+ },
+
+ rule_ref: function(node) {
+ if (arrays.contains(visitedRules, node.name)) {
+ visitedRules.push(node.name);
+
+ throw new GrammarError(
+ "Possible infinite loop when parsing (left recursion: "
+ + visitedRules.join(" -> ")
+ + ").",
+ node.location
+ );
+ }
+
+ check(asts.findRule(ast, node.name));
+ }
+ });
+
+ check(ast);
+}
+
+module.exports = reportInfiniteRecursion;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-repetition.js b/cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-repetition.js
new file mode 100644
index 0000000..e6f12c0
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/report-infinite-repetition.js
@@ -0,0 +1,35 @@
+"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 reportInfiniteRepetition(ast) {
+ var check = visitor.build({
+ zero_or_more: function(node) {
+ if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
+ throw new GrammarError(
+ "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
+ node.location
+ );
+ }
+ },
+
+ one_or_more: function(node) {
+ if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
+ throw new GrammarError(
+ "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
+ node.location
+ );
+ }
+ }
+ });
+
+ check(ast);
+}
+
+module.exports = reportInfiniteRepetition;
diff --git a/cordova/node_modules/pegjs/lib/compiler/passes/report-undefined-rules.js b/cordova/node_modules/pegjs/lib/compiler/passes/report-undefined-rules.js
new file mode 100644
index 0000000..c71b03f
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/passes/report-undefined-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 reportUndefinedRules(ast) {
+ var check = visitor.build({
+ rule_ref: function(node) {
+ if (!asts.findRule(ast, node.name)) {
+ throw new GrammarError(
+ "Rule \"" + node.name + "\" is not defined.",
+ node.location
+ );
+ }
+ }
+ });
+
+ check(ast);
+}
+
+module.exports = reportUndefinedRules;
diff --git a/cordova/node_modules/pegjs/lib/compiler/visitor.js b/cordova/node_modules/pegjs/lib/compiler/visitor.js
new file mode 100644
index 0000000..0a447bc
--- /dev/null
+++ b/cordova/node_modules/pegjs/lib/compiler/visitor.js
@@ -0,0 +1,72 @@
+"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,
+ group: 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;