diff --git a/Makefile b/Makefile index 2d4e65b..0f7a5bf 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ MODULES = utils \ grammar-error \ parser \ compiler/opcodes \ + compiler/flags \ compiler/passes/generate-bytecode \ compiler/passes/generate-javascript \ compiler/passes/remove-proxy-rules \ diff --git a/README.md b/README.md index eea37ca..05f7acc 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,11 @@ expression as its arguments. The action should return some JavaScript value using the `return` statement. This value is considered match result of the preceding expression. +To indicate a match failure, the code inside the action can invoke the +`expected` function. It takes one parameter — a description of what was expected +at the current position. This description will be used as part of a message of +the exception thrown if the match failure leads to an parse error. + The code inside the action can access all variables and functions defined in the initializer at the beginning of the grammar. Curly braces in the action code must be balanced. diff --git a/lib/compiler/flags.js b/lib/compiler/flags.js new file mode 100644 index 0000000..384ca96 --- /dev/null +++ b/lib/compiler/flags.js @@ -0,0 +1,6 @@ +/* Bytecode instruction flags. */ +module.exports = { + DONT_CHECK_FAILS: 0, + CHECK_FAILS: 1 +}; + diff --git a/lib/compiler/passes/generate-bytecode.js b/lib/compiler/passes/generate-bytecode.js index 9f13c7b..772af78 100644 --- a/lib/compiler/passes/generate-bytecode.js +++ b/lib/compiler/passes/generate-bytecode.js @@ -1,5 +1,6 @@ var utils = require("../../utils"), - op = require("../opcodes"); + op = require("../opcodes"), + flags = require("../flags"); /* Generates bytecode. * @@ -151,9 +152,9 @@ var utils = require("../../utils"), * * reportedPos = currPos; * - * [23] CALL f, n, pc, p1, p2, ..., pN + * [23] CALL f, c, n, pc, p1, p2, ..., pN * - * value = consts[f](stack[p1], ..., stack[pN]); + * value = call(consts[f], c, stack[p1], ..., stack[pN]); * stack.pop(n); * stack.push(value); * @@ -206,10 +207,16 @@ module.exports = function(ast, options) { return condCode.concat([bodyCode.length], bodyCode); } - function buildCall(functionIndex, delta, env, sp) { + function buildCall(functionIndex, checkFails, delta, env, sp) { var params = utils.map( utils.values(env), function(p) { return sp - p; }); - return [op.CALL, functionIndex, delta, params.length].concat(params); + return [ + op.CALL, + functionIndex, + checkFails, + delta, + params.length + ].concat(params); } function buildSimplePredicate(expression, negative, context) { @@ -248,7 +255,13 @@ module.exports = function(ast, options) { return buildSequence( [op.REPORT_CURR_POS], - buildCall(functionIndex, 0, context.env, context.sp), + buildCall( + functionIndex, + flags.DONT_CHECK_FAILS, + 0, + context.env, + context.sp + ), buildCondition( [op.IF], buildSequence( @@ -347,7 +360,13 @@ module.exports = function(ast, options) { [op.IF_NOT_ERROR], buildSequence( [op.REPORT_SAVED_POS, 1], - buildCall(functionIndex, 1, env, context.sp + 2) + buildCall( + functionIndex, + flags.CHECK_FAILS, + 1, + env, + context.sp + 2 + ) ), [] ), @@ -396,6 +415,7 @@ module.exports = function(ast, options) { [op.REPORT_SAVED_POS, node.elements.length], buildCall( functionIndex, + flags.CHECK_FAILS, node.elements.length, context.env, context.sp diff --git a/lib/compiler/passes/generate-javascript.js b/lib/compiler/passes/generate-javascript.js index fadd891..90cccba 100644 --- a/lib/compiler/passes/generate-javascript.js +++ b/lib/compiler/passes/generate-javascript.js @@ -1,5 +1,6 @@ var utils = require("../../utils"), - op = require("../opcodes"); + op = require("../opcodes"), + flags = require("../flags"); /* Generates parser JavaScript code. */ module.exports = function(ast, options) { @@ -102,7 +103,7 @@ module.exports = function(ast, options) { } function generateCall() { - var baseLength = 4, + var baseLength = 5, paramsLengthCode = 'bc[ip + ' + (baseLength - 1) + ']'; return [ @@ -111,11 +112,15 @@ module.exports = function(ast, options) { ' 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)', - ');', + 'if (bc[ip + 2] === ' + flags.CHECK_FAILS + ') {', + ' peg$userFail = false;', + '}', + 'result = peg$consts[bc[ip + 1]].apply(null, params);', + 'if (bc[ip + 2] === ' + flags.CHECK_FAILS + ') {', + ' if (peg$userFail) { result = peg$FAILED; }', + '}', + '', + 'stack.splice(stack.length - bc[ip + 3], bc[ip + 3], result);', '', 'ip += ' + baseLength + ' + ' + paramsLengthCode + ';', 'break;' @@ -140,7 +145,7 @@ module.exports = function(ast, options) { ' end = bc.length,', ' ends = [],', ' stack = [],', - ' params, i;', + ' params, result, i;', '' ].join('\n')); @@ -272,7 +277,7 @@ module.exports = function(ast, options) { ' case ' + op.FAIL + ':', // FAIL e ' stack.push(peg$FAILED);', ' if (peg$silentFails === 0) {', - ' peg$fail(peg$consts[bc[ip + 1]]);', + ' peg$fail(peg$consts[bc[ip + 1]], peg$currPos);', ' }', ' ip += 2;', ' break;', @@ -419,7 +424,7 @@ module.exports = function(ast, options) { } function compileCall(cond) { - var baseLength = 4, + var baseLength = 5, paramsLength = bc[ip + baseLength - 1]; var value = c(bc[ip + 1]) + '(' @@ -428,8 +433,14 @@ module.exports = function(ast, options) { stackIndex ).join(', ') + ')'; - stack.pop(bc[ip + 2]); + stack.pop(bc[ip + 3]); + if (bc[ip + 2] === flags.CHECK_FAILS) { + parts.push('peg$userFail = false;'); + } parts.push(stack.push(value)); + if (bc[ip + 2] === flags.CHECK_FAILS) { + parts.push('if (peg$userFail) { ' + stack.top() + ' = peg$FAILED; }'); + } ip += baseLength + paramsLength; } @@ -586,7 +597,7 @@ module.exports = function(ast, options) { case op.FAIL: // FAIL e parts.push(stack.push('peg$FAILED')); - parts.push('if (peg$silentFails === 0) { peg$fail(' + c(bc[ip + 1]) + '); }'); + parts.push('if (peg$silentFails === 0) { peg$fail(' + c(bc[ip + 1]) + ', peg$currPos); }'); ip += 2; break; @@ -791,6 +802,7 @@ module.exports = function(ast, options) { ' peg$maxFailPos = 0,', ' peg$maxFailExpected = [],', ' peg$silentFails = 0,', // 0 = report failures, > 0 = silence failures + ' peg$userFail = false,', '' ].join('\n')); @@ -843,6 +855,13 @@ module.exports = function(ast, options) { ' return peg$computePosDetails(peg$reportedPos).column;', ' }', '', + ' function expected(description) {', + ' if (peg$silentFails === 0) {', + ' peg$fail({ type: "other", description: description }, peg$reportedPos);', + ' }', + ' peg$userFail = true;', + ' }', + '', ' function peg$computePosDetails(pos) {', ' function advance(details, startPos, endPos) {', ' var p, ch;', @@ -876,11 +895,11 @@ module.exports = function(ast, options) { ' return peg$cachedPosDetails;', ' }', '', - ' function peg$fail(expected) {', - ' if (peg$currPos < peg$maxFailPos) { return; }', + ' function peg$fail(expected, pos) {', + ' if (pos < peg$maxFailPos) { return; }', '', - ' if (peg$currPos > peg$maxFailPos) {', - ' peg$maxFailPos = peg$currPos;', + ' if (pos > peg$maxFailPos) {', + ' peg$maxFailPos = pos;', ' peg$maxFailExpected = [];', ' }', '', @@ -888,7 +907,7 @@ module.exports = function(ast, options) { ' }', '', ' function peg$cleanupExpected(expected) {', - ' var i = 0;', + ' var i = 1;', '', ' expected.sort(function(a, b) {', ' if (a.description < b.description) {', @@ -900,13 +919,8 @@ module.exports = function(ast, options) { ' }', ' });', '', - /* - * 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]) {', + ' if (expected[i - 1].description === expected[i].description) {', ' expected.splice(i, 1);', ' } else {', ' i++;', diff --git a/lib/parser.js b/lib/parser.js index 65ee165..3e9069c 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -387,6 +387,7 @@ module.exports = (function() { peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, + peg$userFail = false, peg$result; @@ -414,6 +415,13 @@ module.exports = (function() { return peg$computePosDetails(peg$reportedPos).column; } + function expected(description) { + if (peg$silentFails === 0) { + peg$fail({ type: "other", description: description }, peg$reportedPos); + } + peg$userFail = true; + } + function peg$computePosDetails(pos) { function advance(details, startPos, endPos) { var p, ch; @@ -447,11 +455,11 @@ module.exports = (function() { return peg$cachedPosDetails; } - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } + function peg$fail(expected, pos) { + if (pos < peg$maxFailPos) { return; } - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; + if (pos > peg$maxFailPos) { + peg$maxFailPos = pos; peg$maxFailExpected = []; } @@ -459,7 +467,7 @@ module.exports = (function() { } function peg$cleanupExpected(expected) { - var i = 0; + var i = 1; expected.sort(function(a, b) { if (a.description < b.description) { @@ -472,7 +480,7 @@ module.exports = (function() { }); while (i < expected.length) { - if (expected[i - 1] === expected[i]) { + if (expected[i - 1].description === expected[i].description) { expected.splice(i, 1); } else { i++; @@ -503,7 +511,9 @@ module.exports = (function() { } if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c3(s2, s3); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -538,7 +548,9 @@ module.exports = (function() { } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c4(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -578,7 +590,9 @@ module.exports = (function() { } if (s5 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c5(s1, s2, s4); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -651,7 +665,9 @@ module.exports = (function() { } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c6(s1, s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -684,7 +700,9 @@ module.exports = (function() { s2 = peg$parseaction(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c7(s1, s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -709,7 +727,9 @@ module.exports = (function() { } if (s1 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c8(s1); + if (peg$userFail) { s1 = peg$FAILED; } } if (s1 === peg$FAILED) { peg$currPos = s0; @@ -733,7 +753,9 @@ module.exports = (function() { s3 = peg$parseprefixed(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c9(s1, s3); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -768,7 +790,9 @@ module.exports = (function() { s2 = peg$parsesuffixed(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c10(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -790,7 +814,9 @@ module.exports = (function() { s2 = peg$parseaction(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c11(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -812,7 +838,9 @@ module.exports = (function() { s2 = peg$parsesuffixed(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c12(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -834,7 +862,9 @@ module.exports = (function() { s2 = peg$parseaction(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c13(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -856,7 +886,9 @@ module.exports = (function() { s2 = peg$parsesuffixed(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c14(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -891,7 +923,9 @@ module.exports = (function() { s2 = peg$parsequestion(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c15(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -913,7 +947,9 @@ module.exports = (function() { s2 = peg$parsestar(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c16(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -935,7 +971,9 @@ module.exports = (function() { s2 = peg$parseplus(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c17(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -994,7 +1032,9 @@ module.exports = (function() { } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c19(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1018,7 +1058,9 @@ module.exports = (function() { s1 = peg$parsedot(); if (s1 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c20(); + if (peg$userFail) { s1 = peg$FAILED; } } if (s1 === peg$FAILED) { peg$currPos = s0; @@ -1035,7 +1077,9 @@ module.exports = (function() { s3 = peg$parserparen(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c21(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1072,7 +1116,9 @@ module.exports = (function() { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c23(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1090,7 +1136,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c22); } + if (peg$silentFails === 0) { peg$fail(peg$c22, peg$currPos); } } return s0; @@ -1106,7 +1152,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c25); } + if (peg$silentFails === 0) { peg$fail(peg$c25, peg$currPos); } } if (s2 !== peg$FAILED) { s3 = []; @@ -1127,7 +1173,7 @@ module.exports = (function() { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c27); } + if (peg$silentFails === 0) { peg$fail(peg$c27, peg$currPos); } } if (s4 !== peg$FAILED) { s2 = [s2, s3, s4]; @@ -1177,7 +1223,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c29); } + if (peg$silentFails === 0) { peg$fail(peg$c29, peg$currPos); } } return s0; @@ -1192,13 +1238,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c31); } + if (peg$silentFails === 0) { peg$fail(peg$c31, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c32(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1226,13 +1274,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c34); } + if (peg$silentFails === 0) { peg$fail(peg$c34, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c35(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1260,13 +1310,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c37); } + if (peg$silentFails === 0) { peg$fail(peg$c37, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c38(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1294,13 +1346,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c40); } + if (peg$silentFails === 0) { peg$fail(peg$c40, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c41(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1328,13 +1382,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c43); } + if (peg$silentFails === 0) { peg$fail(peg$c43, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c44(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1362,13 +1418,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c46); } + if (peg$silentFails === 0) { peg$fail(peg$c46, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c47(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1396,13 +1454,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c49); } + if (peg$silentFails === 0) { peg$fail(peg$c49, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c50(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1430,13 +1490,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c52); } + if (peg$silentFails === 0) { peg$fail(peg$c52, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c53(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1464,13 +1526,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c55); } + if (peg$silentFails === 0) { peg$fail(peg$c55, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c56(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1498,13 +1562,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c58); } + if (peg$silentFails === 0) { peg$fail(peg$c58, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c59(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1532,13 +1598,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c61); } + if (peg$silentFails === 0) { peg$fail(peg$c61, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c62(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1566,13 +1634,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c64); } + if (peg$silentFails === 0) { peg$fail(peg$c64, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c65(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1600,13 +1670,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c67); } + if (peg$silentFails === 0) { peg$fail(peg$c67, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c68(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1639,7 +1711,7 @@ module.exports = (function() { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c71); } + if (peg$silentFails === 0) { peg$fail(peg$c71, peg$currPos); } } } if (s3 !== peg$FAILED) { @@ -1653,7 +1725,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c71); } + if (peg$silentFails === 0) { peg$fail(peg$c71, peg$currPos); } } } } @@ -1668,7 +1740,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c71); } + if (peg$silentFails === 0) { peg$fail(peg$c71, peg$currPos); } } } } @@ -1692,7 +1764,9 @@ module.exports = (function() { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c72(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1710,7 +1784,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c69); } + if (peg$silentFails === 0) { peg$fail(peg$c69, peg$currPos); } } return s0; @@ -1731,7 +1805,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c75); } + if (peg$silentFails === 0) { peg$fail(peg$c75, peg$currPos); } } if (s2 === peg$FAILED) { s2 = peg$c1; @@ -1740,7 +1814,9 @@ module.exports = (function() { s3 = peg$parse__(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c76(s1, s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1762,7 +1838,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c73); } + if (peg$silentFails === 0) { peg$fail(peg$c73, peg$currPos); } } return s0; @@ -1781,7 +1857,9 @@ module.exports = (function() { s2 = peg$parse__(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c78(s1); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1799,7 +1877,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c77); } + if (peg$silentFails === 0) { peg$fail(peg$c77, peg$currPos); } } return s0; @@ -1814,7 +1892,7 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c80); } + if (peg$silentFails === 0) { peg$fail(peg$c80, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1829,11 +1907,13 @@ module.exports = (function() { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c80); } + if (peg$silentFails === 0) { peg$fail(peg$c80, peg$currPos); } } if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c81(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1890,7 +1970,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c80); } + if (peg$silentFails === 0) { peg$fail(peg$c80, peg$currPos); } } if (s2 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 92) { @@ -1898,7 +1978,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c83, peg$currPos); } } if (s2 === peg$FAILED) { s2 = peg$parseeolChar(); @@ -1917,11 +1997,13 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c85(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -1949,7 +2031,7 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c87); } + if (peg$silentFails === 0) { peg$fail(peg$c87, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = []; @@ -1964,11 +2046,13 @@ module.exports = (function() { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c87); } + if (peg$silentFails === 0) { peg$fail(peg$c87, peg$currPos); } } if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c81(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2025,7 +2109,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c87); } + if (peg$silentFails === 0) { peg$fail(peg$c87, peg$currPos); } } if (s2 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 92) { @@ -2033,7 +2117,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c83, peg$currPos); } } if (s2 === peg$FAILED) { s2 = peg$parseeolChar(); @@ -2052,11 +2136,13 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c85(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2085,7 +2171,7 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c90); } + if (peg$silentFails === 0) { peg$fail(peg$c90, peg$currPos); } } if (s1 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 94) { @@ -2093,7 +2179,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c92); } + if (peg$silentFails === 0) { peg$fail(peg$c92, peg$currPos); } } if (s2 === peg$FAILED) { s2 = peg$c1; @@ -2117,7 +2203,7 @@ module.exports = (function() { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c94); } + if (peg$silentFails === 0) { peg$fail(peg$c94, peg$currPos); } } if (s4 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 105) { @@ -2125,7 +2211,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c75); } + if (peg$silentFails === 0) { peg$fail(peg$c75, peg$currPos); } } if (s5 === peg$FAILED) { s5 = peg$c1; @@ -2134,7 +2220,9 @@ module.exports = (function() { s6 = peg$parse__(); if (s6 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c95(s2, s3, s5); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2168,7 +2256,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c88); } + if (peg$silentFails === 0) { peg$fail(peg$c88, peg$currPos); } } return s0; @@ -2185,13 +2273,15 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c97); } + if (peg$silentFails === 0) { peg$fail(peg$c97, peg$currPos); } } if (s2 !== peg$FAILED) { s3 = peg$parseclassCharacter(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c98(s1, s3); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2221,7 +2311,9 @@ module.exports = (function() { s1 = peg$parsebracketDelimitedCharacter(); if (s1 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c99(s1); + if (peg$userFail) { s1 = peg$FAILED; } } if (s1 === peg$FAILED) { peg$currPos = s0; @@ -2267,7 +2359,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c94); } + if (peg$silentFails === 0) { peg$fail(peg$c94, peg$currPos); } } if (s2 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 92) { @@ -2275,7 +2367,7 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c83, peg$currPos); } } if (s2 === peg$FAILED) { s2 = peg$parseeolChar(); @@ -2294,11 +2386,13 @@ module.exports = (function() { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c85(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2326,7 +2420,7 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c83, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$currPos; @@ -2338,7 +2432,7 @@ module.exports = (function() { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c101); } + if (peg$silentFails === 0) { peg$fail(peg$c101, peg$currPos); } } if (s3 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 117) { @@ -2346,7 +2440,7 @@ module.exports = (function() { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c103); } + if (peg$silentFails === 0) { peg$fail(peg$c103, peg$currPos); } } if (s3 === peg$FAILED) { s3 = peg$parseeolChar(); @@ -2366,11 +2460,13 @@ module.exports = (function() { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s3 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c104(s3); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2402,7 +2498,7 @@ module.exports = (function() { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c106); } + if (peg$silentFails === 0) { peg$fail(peg$c106, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$currPos; @@ -2417,7 +2513,9 @@ module.exports = (function() { } if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c107(); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2445,7 +2543,7 @@ module.exports = (function() { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c109); } + if (peg$silentFails === 0) { peg$fail(peg$c109, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$currPos; @@ -2470,7 +2568,9 @@ module.exports = (function() { s2 = s3; if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c110(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2498,7 +2598,7 @@ module.exports = (function() { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c112); } + if (peg$silentFails === 0) { peg$fail(peg$c112, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$currPos; @@ -2535,7 +2635,9 @@ module.exports = (function() { s2 = s3; if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c110(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2563,13 +2665,15 @@ module.exports = (function() { peg$currPos++; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c83); } + if (peg$silentFails === 0) { peg$fail(peg$c83, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = peg$parseeol(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; + peg$userFail = false; s1 = peg$c113(s2); + if (peg$userFail) { s1 = peg$FAILED; } if (s1 === peg$FAILED) { peg$currPos = s0; s0 = s1; @@ -2596,7 +2700,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c115); } + if (peg$silentFails === 0) { peg$fail(peg$c115, peg$currPos); } } return s0; @@ -2610,7 +2714,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c117); } + if (peg$silentFails === 0) { peg$fail(peg$c117, peg$currPos); } } return s0; @@ -2635,7 +2739,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c119); } + if (peg$silentFails === 0) { peg$fail(peg$c119, peg$currPos); } } return s0; @@ -2649,7 +2753,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c121); } + if (peg$silentFails === 0) { peg$fail(peg$c121, peg$currPos); } } return s0; @@ -2691,7 +2795,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c122); } + if (peg$silentFails === 0) { peg$fail(peg$c122, peg$currPos); } } return s0; @@ -2706,7 +2810,7 @@ module.exports = (function() { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c124); } + if (peg$silentFails === 0) { peg$fail(peg$c124, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = []; @@ -2727,7 +2831,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s5 !== peg$FAILED) { s4 = [s4, s5]; @@ -2759,7 +2863,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s5 !== peg$FAILED) { s4 = [s4, s5]; @@ -2797,7 +2901,7 @@ module.exports = (function() { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c126); } + if (peg$silentFails === 0) { peg$fail(peg$c126, peg$currPos); } } if (s1 !== peg$FAILED) { s2 = []; @@ -2809,7 +2913,7 @@ module.exports = (function() { peg$currPos += 2; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c128); } + if (peg$silentFails === 0) { peg$fail(peg$c128, peg$currPos); } } peg$silentFails--; if (s5 === peg$FAILED) { @@ -2824,7 +2928,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s5 !== peg$FAILED) { s4 = [s4, s5]; @@ -2847,7 +2951,7 @@ module.exports = (function() { peg$currPos += 2; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c128); } + if (peg$silentFails === 0) { peg$fail(peg$c128, peg$currPos); } } peg$silentFails--; if (s5 === peg$FAILED) { @@ -2862,7 +2966,7 @@ module.exports = (function() { peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c84); } + if (peg$silentFails === 0) { peg$fail(peg$c84, peg$currPos); } } if (s5 !== peg$FAILED) { s4 = [s4, s5]; @@ -2882,7 +2986,7 @@ module.exports = (function() { peg$currPos += 2; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c128); } + if (peg$silentFails === 0) { peg$fail(peg$c128, peg$currPos); } } if (s3 !== peg$FAILED) { s1 = [s1, s2, s3]; @@ -2912,7 +3016,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c131); } + if (peg$silentFails === 0) { peg$fail(peg$c131, peg$currPos); } } if (s0 === peg$FAILED) { if (input.substr(peg$currPos, 2) === peg$c132) { @@ -2920,7 +3024,7 @@ module.exports = (function() { peg$currPos += 2; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c133); } + if (peg$silentFails === 0) { peg$fail(peg$c133, peg$currPos); } } if (s0 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 13) { @@ -2928,7 +3032,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c135); } + if (peg$silentFails === 0) { peg$fail(peg$c135, peg$currPos); } } if (s0 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8232) { @@ -2936,7 +3040,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c137); } + if (peg$silentFails === 0) { peg$fail(peg$c137, peg$currPos); } } if (s0 === peg$FAILED) { if (input.charCodeAt(peg$currPos) === 8233) { @@ -2944,7 +3048,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c139); } + if (peg$silentFails === 0) { peg$fail(peg$c139, peg$currPos); } } } } @@ -2953,7 +3057,7 @@ module.exports = (function() { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c129); } + if (peg$silentFails === 0) { peg$fail(peg$c129, peg$currPos); } } return s0; @@ -2967,7 +3071,7 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c141); } + if (peg$silentFails === 0) { peg$fail(peg$c141, peg$currPos); } } return s0; @@ -2982,12 +3086,12 @@ module.exports = (function() { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c144); } + if (peg$silentFails === 0) { peg$fail(peg$c144, peg$currPos); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c142); } + if (peg$silentFails === 0) { peg$fail(peg$c142, peg$currPos); } } return s0; diff --git a/package.json b/package.json index fa2fcfb..645eb3f 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "examples/json.pegjs", "lib/compiler.js", "lib/compiler/opcodes.js", + "lib/compiler/flags.js", "lib/compiler/passes/generate-bytecode.js", "lib/compiler/passes/generate-javascript.js", "lib/compiler/passes/remove-proxy-rules.js", diff --git a/spec/compiler/passes/generate-bytecode.spec.js b/spec/compiler/passes/generate-bytecode.spec.js index 84ed6b6..1a59668 100644 --- a/spec/compiler/passes/generate-bytecode.spec.js +++ b/spec/compiler/passes/generate-bytecode.spec.js @@ -89,14 +89,14 @@ describe("compiler pass |generateBytecode|", function() { it("generates correct bytecode", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ - 1, // PUSH_CURR_POS - 0, 0, // PUSH - 12, 6, 0, // IF_NOT_ERROR - 21, 1, // * REPORT_SAVED_POS - 23, 1, 1, 0, // CALL - 11, 1, 1, // IF_ERROR - 6, // * NIP_CURR_POS - 5 // * NIP + 1, // PUSH_CURR_POS + 0, 0, // PUSH + 12, 7, 0, // IF_NOT_ERROR + 21, 1, // * REPORT_SAVED_POS + 23, 1, 1, 1, 0, // CALL + 11, 1, 1, // IF_ERROR + 6, // * NIP_CURR_POS + 5 // * NIP ])); }); @@ -115,9 +115,9 @@ describe("compiler pass |generateBytecode|", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ 1, // PUSH_CURR_POS 15, 0, 2, 2, 19, 0, 20, 1, // - 12, 7, 0, // IF_NOT_ERROR + 12, 8, 0, // IF_NOT_ERROR 21, 1, // * REPORT_SAVED_POS - 23, 2, 1, 1, 0, // CALL + 23, 2, 1, 1, 1, 0, // CALL 11, 1, 1, // IF_ERROR 6, // * NIP_CURR_POS 5 // * NIP @@ -139,13 +139,13 @@ describe("compiler pass |generateBytecode|", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ 1, // PUSH_CURR_POS 15, 1, 2, 2, 19, 1, 20, 2, // - 12, 46, 4, // IF_NOT_ERROR + 12, 47, 4, // IF_NOT_ERROR 15, 3, 2, 2, 19, 3, 20, 4, // * - 12, 30, 5, // IF_NOT_ERROR + 12, 31, 5, // IF_NOT_ERROR 15, 5, 2, 2, 19, 5, 20, 6, // * - 12, 14, 5, // IF_NOT_ERROR + 12, 15, 5, // IF_NOT_ERROR 21, 3, // * REPORT_SAVED_POS - 23, 7, 3, 3, 2, 1, 0, // CALL + 23, 7, 1, 3, 3, 2, 1, 0, // CALL 11, 1, 1, // IF_ERROR 6, // * NIP_CURR_POS 5, // * NIP @@ -315,13 +315,13 @@ describe("compiler pass |generateBytecode|", function() { it("generates correct bytecode", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ - 22, // REPORT_CURR_POS - 23, 0, 0, 0, // CALL - 10, 3, 3, // IF - 2, // * POP - 0, 1, // PUSH - 2, // * POP - 0, 2 // PUSH + 22, // REPORT_CURR_POS + 23, 0, 0, 0, 0, // CALL + 10, 3, 3, // IF + 2, // * POP + 0, 1, // PUSH + 2, // * POP + 0, 2 // PUSH ])); }); @@ -340,13 +340,13 @@ describe("compiler pass |generateBytecode|", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ 1, // PUSH_CURR_POS 15, 1, 2, 2, 19, 1, 20, 2, // - 12, 60, 4, // IF_NOT_ERROR + 12, 61, 4, // IF_NOT_ERROR 15, 3, 2, 2, 19, 3, 20, 4, // * - 12, 44, 5, // IF_NOT_ERROR + 12, 45, 5, // IF_NOT_ERROR 15, 5, 2, 2, 19, 5, 20, 6, // * - 12, 28, 5, // IF_NOT_ERROR + 12, 29, 5, // IF_NOT_ERROR 22, // * REPORT_CURR_POS - 23, 7, 0, 3, 2, 1, 0, // CALL + 23, 7, 0, 0, 3, 2, 1, 0, // CALL 10, 3, 3, // IF 2, // * POP 0, 8, // PUSH @@ -392,13 +392,13 @@ describe("compiler pass |generateBytecode|", function() { it("generates correct bytecode", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ - 22, // REPORT_CURR_POS - 23, 0, 0, 0, // CALL_PREDICATE - 10, 3, 3, // IF - 2, // * POP - 0, 2, // PUSH - 2, // * POP - 0, 1 // PUSH + 22, // REPORT_CURR_POS + 23, 0, 0, 0, 0, // CALL_PREDICATE + 10, 3, 3, // IF + 2, // * POP + 0, 2, // PUSH + 2, // * POP + 0, 1 // PUSH ])); }); @@ -417,13 +417,13 @@ describe("compiler pass |generateBytecode|", function() { expect(pass).toChangeAST(grammar, bytecodeDetails([ 1, // PUSH_CURR_POS 15, 1, 2, 2, 19, 1, 20, 2, // - 12, 60, 4, // IF_NOT_ERROR + 12, 61, 4, // IF_NOT_ERROR 15, 3, 2, 2, 19, 3, 20, 4, // * - 12, 44, 5, // IF_NOT_ERROR + 12, 45, 5, // IF_NOT_ERROR 15, 5, 2, 2, 19, 5, 20, 6, // * - 12, 28, 5, // IF_NOT_ERROR + 12, 29, 5, // IF_NOT_ERROR 22, // * REPORT_CURR_POS - 23, 7, 0, 3, 2, 1, 0, // CALL + 23, 7, 0, 0, 3, 2, 1, 0, // CALL 10, 3, 3, // IF 2, // * POP 0, 0, // PUSH diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index 8abbb73..cfabe0d 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -337,6 +337,66 @@ describe("generated parser", function() { expect(parser).toParse("a", 42); }); + describe("|expected| function", function() { + it("generates a regular match failure", function() { + var parser = PEG.buildParser( + 'start = "a" { expected("a"); }', + options + ); + + expect(parser).toFailToParse("a", { + offset: 0, + line: 1, + column: 1, + expected: [{ type: "other", description: "a" }], + found: "a", + message: 'Expected a but "a" found.' + }); + }); + + it("generated failures combine with failures generated before", function() { + var parser = PEG.buildParser( + 'start = "a" / ("b" { expected("b"); })', + options + ); + + expect(parser).toFailToParse("b", { + expected: [ + { type: "literal", value: "a", description: '"a"' }, + { type: "other", description: "b" } + ] + }); + }); + + it("generated failures combine with failures generated after", function() { + var parser = PEG.buildParser( + 'start = ("a" { expected("a"); }) / "b"', + options + ); + + expect(parser).toFailToParse("a", { + expected: [ + { type: "literal", value: "b", description: '"b"' }, + { type: "other", description: "a" } + ] + }); + }); + + it("multiple invocations generate additional failures", function() { + var parser = PEG.buildParser( + 'start = "a" { expected("a1"); expected("a2"); }', + options + ); + + expect(parser).toFailToParse("a", { + expected: [ + { type: "other", description: "a1" }, + { type: "other", description: "a2" } + ] + }); + }); + }); + it("can use functions defined in the initializer", function() { var parser = PEG.buildParser([ '{ function f() { return 42; } }',