diff --git a/dist/cli-cjs-es5.js b/dist/cli-cjs-es5.js index 64c764065..ac851c177 100644 --- a/dist/cli-cjs-es5.js +++ b/dist/cli-cjs-es5.js @@ -117,7 +117,7 @@ function _interopDefault(ex) { var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var json5 = _interopDefault(require('@gerhobbelt/json5')); var astUtils = _interopDefault(require('@gerhobbelt/ast-util')); @@ -274,6 +274,13 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -364,6 +371,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -403,13 +411,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -473,15 +481,24 @@ var parse2AST = { checkActionBlock: checkActionBlock }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -753,10 +770,7 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1282,7 +1296,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2871,14 +2886,14 @@ var parser$1 = { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2967,8 +2982,7 @@ var parser$1 = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3523,14 +3537,15 @@ var parser$1 = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -4026,13 +4041,13 @@ var parser$1 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -4045,7 +4060,7 @@ var parser$1 = { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5644,7 +5659,6 @@ var lexer = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6960,7 +6974,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6974,7 +6988,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6983,7 +6997,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -7167,7 +7181,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7433,9 +7447,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7585,8 +7599,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7601,7 +7615,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7715,6 +7729,13 @@ var code_exec$2 = helpers.exec; var version$2 = '0.6.1-215'; // require('./package.json').version; +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7900,7 +7921,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7908,7 +7929,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7989,6 +8010,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -8129,7 +8151,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -8186,7 +8208,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -8241,7 +8263,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -8286,7 +8308,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8377,7 +8399,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8414,7 +8436,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8479,7 +8501,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8526,7 +8548,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8659,7 +8681,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8683,6 +8705,7 @@ function RegExpLexer(dict, input, tokens, build_options) { var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8749,11 +8772,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8764,14 +8787,14 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8784,8 +8807,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8796,8 +8819,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8890,6 +8913,7 @@ function getRegExpLexerPrototype() { // --- END lexer kernel --- } +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS$3(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8953,6 +8977,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -9111,6 +9136,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -9177,9 +9203,9 @@ function generateModuleBody(opt) { protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -9214,8 +9240,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -9316,7 +9342,7 @@ RegExpLexer.camelCase = helpers.camelCase; RegExpLexer.mkIdentifier = mkIdentifier$4; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -9830,7 +9856,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -10592,13 +10619,13 @@ var parser$3 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -10610,7 +10637,7 @@ var parser$3 = { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -12701,10 +12728,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13230,7 +13254,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -14862,14 +14887,14 @@ var parser$2 = { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -14958,8 +14983,7 @@ var parser$2 = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -15514,14 +15538,15 @@ var parser$2 = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -16017,13 +16042,13 @@ var parser$2 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -16036,7 +16061,7 @@ var parser$2 = { }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17635,7 +17660,6 @@ var lexer$1 = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -19273,6 +19297,13 @@ var version$1 = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -19294,6 +19325,7 @@ var defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -19321,7 +19353,7 @@ var defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -19692,8 +19724,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -19954,13 +19986,26 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -20252,21 +20297,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -20274,7 +20319,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -20287,12 +20332,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -20613,7 +20658,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens // as used in a rule like this: `rule: A ' ' B;` which should produce 3 tokens for the @@ -20635,7 +20680,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -20715,12 +20760,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -20749,8 +20794,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -20758,7 +20803,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } else { @@ -20946,10 +20991,10 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { } function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); - var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode.join(','), self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, '======================================', self.performAction, '======================================']; - return h.join(','); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); + var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode, self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, self.options.moduleName, self.options.parseParams, self.options.ranges, self.options.prettyCfg, '======================================', self.performAction, '======================================']; + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -20977,8 +21022,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include).replace(/#([^#\s\r\n]+)#/g, function (_, sym) { @@ -20986,7 +21031,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -21027,7 +21072,7 @@ generator.buildProductionActions = function buildProductionActions() { if (missingActions.length) { console.warn("WARNING: missing actions for states: ", missingActions); - actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n var r = yyparser.parseError(str, hash, yyparser.JisonParserError);\n return r;\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); + actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n return yyparser.parseError(str, hash, yyparser.JisonParserError);\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); } actions.push('}'); @@ -21138,8 +21183,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -21280,6 +21325,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch }); } @@ -21291,12 +21337,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -21411,8 +21457,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -21592,7 +21638,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -21884,7 +21930,8 @@ generator.createLexer = function createLexer() { }; // no-op. implemented in debug mixin -generator.trace = function no_op_trace() {}; +generator.trace = new Function('', 'function no_op_trace() { }\nreturn no_op_trace;')(); +//generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -21978,20 +22025,14 @@ generator.reportGrammarInformation = function reportGrammarInformation() { this.warn('\n'); }; +// --- START of debugTraceSrc chunk --- +var debugTraceSrc = '\nfunction debug_trace() {\n if (typeof Jison !== \'undefined\' && Jison.print) {\n Jison.print.apply(null, arguments);\n } else if (typeof print !== \'undefined\') {\n print.apply(null, arguments);\n } else if (typeof console !== \'undefined\' && console.log) {\n var args = Array.prototype.slice.call(arguments, 0);\n args.unshift(\'\'); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args\n console.log.apply(null, args);\n }\n}\n'; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: new Function('', debugTraceSrc + '\n return debug_trace;')(), beforeprocessGrammar: function beforeprocessGrammar() { this.trace('Processing grammar.'); }, @@ -22033,7 +22074,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -22083,7 +22124,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -22490,7 +22531,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -22634,7 +22675,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -22846,8 +22887,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS$1(_templateObject96, moduleImportsAsCode, moduleNameAsCode.trim())); exportMain = 'main: yyExecMain,'; @@ -22866,8 +22907,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS$1(_templateObject99, moduleImportsAsCode, moduleNameAsCode.trim()); } @@ -23417,7 +23458,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -23425,7 +23466,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -23629,7 +23670,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -23643,7 +23684,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = bprod.newg_states || []; @@ -23777,6 +23818,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -23869,12 +23911,12 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // produce a hash lookup table from the terminal set exportDest.terminalTable = produceTerminalTable(this.terminals_); - var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + this.options.defaultActionMode.join(',') + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; - moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([String(define_parser_APIs_1).replace(/^[\s\S]+?return \{/, '').replace(/\};[s\r\n]+\}\s*$/, '').replace(/^ /mg, '').trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); + var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + JSON.stringify(this.options.defaultActionMode) + '\n // test-compile action mode: ........ ' + JSON.stringify(this.options.testCompileActionCode) + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; + moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -23887,9 +23929,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - - var prelude = '// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';'; - + var prelude = '\n// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';\n'; // --- END parser error class --- return { @@ -23918,6 +23958,10 @@ lrGeneratorMixin.generateTableCode0 = function (table, defaultActions, productio }; }; +// Function that extends an object with the given value for all given keys +// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } +var compressor1ObjectCode = '\nfunction x(k, v, o) {\n o = o || {};\n for (var l = k.length; l--; ) {\n o[k[l]] = v;\n }\n return o;\n}\n'; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -24010,7 +24054,7 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -24028,16 +24072,6 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio }; }; -// Function that extends an object with the given value for all given keys -// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } -function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--;) { - o[k[l]] = v; - } - return o; -} - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -24155,10 +24189,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -24185,7 +24219,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -24224,8 +24258,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -24238,7 +24272,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot === 'undefined' ? 'undefined' : _typeof(slot)) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -24407,10 +24441,13 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -var commonjsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}'; +var commonJsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}\n'; +// --- END of commonJsMain chunk --- -var commonjsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; +var commonJsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; // debug mixin for LR parser generators @@ -24461,6 +24498,7 @@ generatorMixin.createParser = function createParser() { var sourcecode = rmCommonWS$1(_templateObject101, sourceCodeDef.init, sourceCodeDef.src); var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -24468,37 +24506,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(_typeof(p.yy) === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(_typeof(p.yy) === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(_typeof(p.symbols_) === 'object'); - assert(_typeof(p.terminals_) === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(_typeof(p.symbols_) === 'object'); + assert$1(_typeof(p.terminals_) === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(_typeof(p.table) === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(_typeof(p.table) === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(_typeof(p.constructParseErrorInfo) === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(_typeof(p.options) === 'object'); - assert(_typeof(p.cleanupAfterParse) === 'object'); - assert(_typeof(p.yyMergeLocationInfo) === 'object'); - assert(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); + assert$1(_typeof(p.constructParseErrorInfo) === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(_typeof(p.options) === 'object'); + assert$1(_typeof(p.cleanupAfterParse) === 'object'); + assert$1(_typeof(p.yyMergeLocationInfo) === 'object'); + assert$1(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -24535,8 +24573,11 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; -var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}'; // END of parseErrorSourceCode chunk +// --- START parser Error class chunk --- +var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}\n'; +// --- END of parseErrorSourceCode chunk --- +chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -24547,119 +24588,20 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti return lexer; }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, - - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } - - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, - - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. - // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. - // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. - // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } - } - } - return tokenset; - } - }; -} +var define_parser_APIs_1 = '\n TERROR: 2,\n EOF: 1,\n\n // internals: defined here so the object *structure* doesn\'t get modified by parse() et al,\n // thus helping JIT compilers like Chrome V8.\n originalQuoteName: null,\n originalParseError: null,\n cleanupAfterParse: null,\n constructParseErrorInfo: null,\n yyMergeLocationInfo: null,\n\n __reentrant_call_depth: 0, // INTERNAL USE ONLY\n __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n\n // APIs which will be set up depending on user action code analysis:\n //yyRecovering: 0,\n //yyErrOk: 0,\n //yyClearIn: 0,\n\n // Helper APIs\n // -----------\n\n // Helper function which can be overridden by user code later on: put suitable quotes around\n // literal IDs in a description string.\n quoteName: function parser_quoteName(id_str) {\n return \'"\' + id_str + \'"\';\n },\n\n // Return the name of the given symbol (terminal or non-terminal) as a string, when available.\n //\n // Return NULL when the symbol is unknown to the parser.\n getSymbolName: function parser_getSymbolName(symbol) {\n if (this.terminals_[symbol]) {\n return this.terminals_[symbol];\n }\n\n // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up.\n //\n // An example of this may be where a rule\'s action code contains a call like this:\n //\n // parser.getSymbolName(#$)\n //\n // to obtain a human-readable name of the current grammar rule.\n var s = this.symbols_;\n for (var key in s) {\n if (s[key] === symbol) {\n return key;\n }\n }\n return null;\n },\n\n // Return a more-or-less human-readable description of the given symbol, when available,\n // or the symbol itself, serving as its own \'description\' for lack of something better to serve up.\n //\n // Return NULL when the symbol is unknown to the parser.\n describeSymbol: function parser_describeSymbol(symbol) {\n if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) {\n return this.terminal_descriptions_[symbol];\n }\n else if (symbol === this.EOF) {\n return \'end of input\';\n }\n var id = this.getSymbolName(symbol);\n if (id) {\n return this.quoteName(id);\n }\n return null;\n },\n\n // Produce a (more or less) human-readable list of expected tokens at the point of failure.\n //\n // The produced list may contain token or token set descriptions instead of the tokens\n // themselves to help turning this output into something that easier to read by humans\n // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*,\n // expected terminals and nonterminals is produced.\n //\n // The returned list (array) will not contain any duplicate entries.\n collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) {\n var TERROR = this.TERROR;\n var tokenset = [];\n var check = {};\n // Has this (error?) state been outfitted with a custom expectations description text for human consumption?\n // If so, use that one instead of the less palatable token set.\n if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) {\n return [\n this.state_descriptions_[state]\n ];\n }\n for (var p in this.table[state]) {\n p = +p;\n if (p !== TERROR) {\n var d = do_not_describe ? p : this.describeSymbol(p);\n if (d && !check[d]) {\n tokenset.push(d);\n check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries.\n }\n }\n }\n return tokenset;\n }\n'; +// --- END of define_parser_APIs_1 chunk --- -var api_set = define_parser_APIs_1(); +var api_set = new Function('', 'return { ' + define_parser_APIs_1 + ' };')(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- -parser.parse = 'function parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2).replace(re1, \' $1: \').replace(/[\\n\\s]+/g, \' \');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n var r = this.parseError(str, hash, this.JisonParserError);\n return r;\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n else {\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}'; +parser.parse = '\nfunction parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2)\n .replace(re1, \' $1: \')\n .replace(/[\\n\\s]+/g, \' \')\n // shorten yylloc object dumps too:\n .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, \'{L/C: ($1,$2)..($3,$4)\');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n return this.parseError(str, hash, this.JisonParserError);\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}\n'; // --- END parser kernel --- @@ -24708,7 +24650,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function go_(productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -24823,7 +24765,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -24839,7 +24781,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -24850,7 +24792,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -24878,7 +24820,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { @@ -25219,11 +25161,11 @@ Jison.Parser = Parser; var rmCommonWS = helpers.rmCommonWS; var mkIdentifier = helpers.mkIdentifier; -assert(Jison); -assert(typeof Jison.prettyPrint === 'function'); -assert(Jison.defaultJisonOptions); -assert(typeof Jison.mkStdOptions === 'function'); -assert(typeof Jison.Generator === 'function'); +assert$1(Jison); +assert$1(typeof Jison.prettyPrint === 'function'); +assert$1(Jison.defaultJisonOptions); +assert$1(typeof Jison.mkStdOptions === 'function'); +assert$1(typeof Jison.Generator === 'function'); var version = '0.6.1-215'; diff --git a/dist/cli-cjs.js b/dist/cli-cjs.js index bd277e222..33c827fe2 100644 --- a/dist/cli-cjs.js +++ b/dist/cli-cjs.js @@ -8,7 +8,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var json5 = _interopDefault(require('@gerhobbelt/json5')); var astUtils = _interopDefault(require('@gerhobbelt/ast-util')); @@ -169,6 +169,16 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -275,6 +285,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -319,13 +330,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -404,15 +415,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -685,10 +706,7 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1231,7 +1249,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1281,7 +1300,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1439,104 +1458,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4503,14 +4525,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4616,8 +4638,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -5235,7 +5256,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -5245,13 +5265,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5891,13 +5914,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5910,7 +5932,7 @@ yyError: 1 }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7540,7 +7562,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9188,7 +9209,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -9202,7 +9223,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -9211,7 +9232,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9400,7 +9421,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9669,9 +9690,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9824,8 +9845,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9840,7 +9861,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9963,6 +9984,14 @@ var version$2 = '0.6.1-215'; // require('./package. +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -10154,7 +10183,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -10162,7 +10191,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -10243,6 +10272,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10389,7 +10419,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10446,7 +10476,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10501,7 +10531,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10547,7 +10577,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10638,7 +10668,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10675,7 +10705,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10743,7 +10773,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10790,7 +10820,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -11003,7 +11033,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -11032,9 +11062,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -11101,11 +11133,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -11116,7 +11148,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -11126,7 +11158,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -11139,8 +11171,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -11151,8 +11183,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12462,6 +12494,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$3` return ${getRegExpLexerPrototype()}; `))(); @@ -12573,6 +12606,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12731,6 +12765,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12803,9 +12838,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12849,8 +12884,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -13234,7 +13269,7 @@ RegExpLexer.camelCase = helpers.camelCase; RegExpLexer.mkIdentifier = mkIdentifier$4; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13765,7 +13800,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -13815,7 +13851,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13857,104 +13893,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 11, @@ -14907,13 +14946,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -14925,7 +14963,7 @@ parse: function parse(input) { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17097,10 +17135,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -17643,7 +17678,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -17693,7 +17729,7 @@ var parser$2 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -17845,104 +17881,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } + + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ s$1, @@ -20988,14 +21027,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -21101,8 +21140,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -21720,7 +21758,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -21730,13 +21767,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -22376,13 +22416,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -22395,7 +22434,7 @@ yyError: 1 }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -24025,7 +24064,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -26050,6 +26088,14 @@ var version$1 = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -26071,6 +26117,7 @@ const defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -26098,7 +26145,7 @@ const defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -26468,8 +26515,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -26732,13 +26779,26 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -27034,21 +27094,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -27056,7 +27116,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -27069,12 +27129,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -27403,7 +27463,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens @@ -27426,7 +27486,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -27506,12 +27566,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -27540,8 +27600,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -27549,7 +27609,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } @@ -27782,8 +27842,8 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); var h = [ self.actionsAreAllDefault, self.actionsUseLocationAssignment, @@ -27815,7 +27875,8 @@ function mkParserFeatureHash(self) { self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, - self.options.defaultActionMode.join(','), + self.options.defaultActionMode, + self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, @@ -27826,11 +27887,15 @@ function mkParserFeatureHash(self) { self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, + self.options.moduleName, + self.options.parseParams, + self.options.ranges, + self.options.prettyCfg, '======================================', self.performAction, '======================================', ]; - return h.join(','); + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -27860,8 +27925,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include) @@ -27870,7 +27935,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -27936,8 +28001,7 @@ generator.buildProductionActions = function buildProductionActions() { function __b0rk_on_internal_failure(str) { var hash = yyparser.constructParseErrorInfo(str, null, null, false); - var r = yyparser.parseError(str, hash, yyparser.JisonParserError); - return r; + return yyparser.parseError(str, hash, yyparser.JisonParserError); } return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);` @@ -28062,8 +28126,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -28202,6 +28266,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch, }); } @@ -28213,12 +28278,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -28346,8 +28411,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -28533,7 +28598,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -28836,7 +28901,8 @@ generator.createLexer = function createLexer() { }; // no-op. implemented in debug mixin -generator.trace = function no_op_trace() { }; +generator.trace = (new Function('', 'function no_op_trace() { }\nreturn no_op_trace;'))(); +//generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -28930,20 +28996,27 @@ generator.reportGrammarInformation = function reportGrammarInformation() { }; +// --- START of debugTraceSrc chunk --- +const debugTraceSrc = ` +function debug_trace() { + if (typeof Jison !== 'undefined' && Jison.print) { + Jison.print.apply(null, arguments); + } else if (typeof print !== 'undefined') { + print.apply(null, arguments); + } else if (typeof console !== 'undefined' && console.log) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(''); // prevent \`%.\` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args + console.log.apply(null, args); + } +} +`; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: (new Function('', debugTraceSrc + ` + return debug_trace;`))(), beforeprocessGrammar: function () { this.trace('Processing grammar.'); }, @@ -28987,7 +29060,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -29037,7 +29110,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -29440,7 +29513,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -29584,7 +29657,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -30191,8 +30264,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS$1` @@ -30245,8 +30318,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS$1` @@ -30910,7 +30983,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -30918,7 +30991,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -31130,7 +31203,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -31144,7 +31217,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = (bprod.newg_states || []); @@ -31278,6 +31351,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -31377,7 +31451,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // // Options: // - // default action mode: ............. ${this.options.defaultActionMode.join(',')} + // default action mode: ............. ${JSON.stringify(this.options.defaultActionMode)} + // test-compile action mode: ........ ${JSON.stringify(this.options.testCompileActionCode)} // try..catch: ...................... ${!this.options.noTryCatch} // default resolve on conflict: ..... ${!this.options.noDefaultResolve} // on-demand look-ahead: ............ ${this.onDemandLookahead} @@ -31444,11 +31519,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { 'terminal_descriptions_: ' + descrLst : [] ).concat([ - String(define_parser_APIs_1) - .replace(/^[\s\S]+?return \{/, '') - .replace(/\};[s\r\n]+\}\s*$/, '') - .replace(/^ /mg, '') - .trim(), + define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode ]).concat( String(this.performAction).trim() !== '' ? @@ -31479,7 +31550,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -31495,8 +31566,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - -var prelude = `// See also: + const prelude = ` +// See also: // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508 // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility // with userland code which might access the derived class in a 'classic' way. @@ -31545,8 +31616,8 @@ if (typeof Object.setPrototypeOf === 'function') { JisonParserError.prototype = Object.create(Error.prototype); } JisonParserError.prototype.constructor = JisonParserError; -JisonParserError.prototype.name = 'JisonParserError';`; - +JisonParserError.prototype.name = 'JisonParserError'; +`; // --- END parser error class --- return { @@ -31575,6 +31646,18 @@ lrGeneratorMixin.generateTableCode0 = function (table, defaultActions, productio }; }; +// Function that extends an object with the given value for all given keys +// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } +var compressor1ObjectCode = ` +function x(k, v, o) { + o = o || {}; + for (var l = k.length; l--; ) { + o[k[l]] = v; + } + return o; +} +`; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -31665,7 +31748,7 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -31683,16 +31766,6 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio }; }; -// Function that extends an object with the given value for all given keys -// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } -function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--; ) { - o[k[l]] = v; - } - return o; -} - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -31814,10 +31887,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -31847,7 +31920,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -31888,8 +31961,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -31902,7 +31975,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -32071,7 +32144,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var productionsDef = analyzeTableForCompression(productions); - var bp_code_container = ` + const bp_code_container = ` // helper: reconstruct the productions[] table function bp(s) { var rv = []; @@ -32087,7 +32160,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bda_code_container = ` + const bda_code_container = ` // helper: reconstruct the defaultActions[] table function bda(s) { var rv = {}; @@ -32101,7 +32174,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bt_code_container = ` + const bt_code_container = ` // helper: reconstruct the 'goto' table function bt(s) { var rv = []; @@ -32141,7 +32214,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var c_s_u_code_container = ` + const c_s_u_code_container = ` // helper: runlength encoding with increment step: code, length: step (default step = 0) // \`this\` references an array function s(c, l, a) { @@ -32220,8 +32293,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -const commonjsMain = ` +const commonJsMain = ` function (args) { // When the parser comes with its own \`main\` function, then use that one: if (typeof exports.parser.main === 'function') { @@ -32246,9 +32321,11 @@ function (args) { rv = dst; } return dst; -}`; +} +`; +// --- END of commonJsMain chunk --- -const commonjsMainImports = ` +const commonJsMainImports = ` var fs = require('fs'); var path = require('path'); `; @@ -32317,6 +32394,7 @@ generatorMixin.createParser = function createParser() { `; var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -32324,37 +32402,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert(typeof p === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(typeof p.yy === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1(typeof p === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(typeof p.yy === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(typeof p.symbols_ === 'object'); - assert(typeof p.terminals_ === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(typeof p.symbols_ === 'object'); + assert$1(typeof p.terminals_ === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(typeof p.table === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(typeof p.table === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(typeof p.constructParseErrorInfo === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(typeof p.options === 'object'); - assert(typeof p.cleanupAfterParse === 'object'); - assert(typeof p.yyMergeLocationInfo === 'object'); - assert(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); + assert$1(typeof p.constructParseErrorInfo === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(typeof p.options === 'object'); + assert$1(typeof p.cleanupAfterParse === 'object'); + assert$1(typeof p.yyMergeLocationInfo === 'object'); + assert$1(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -32391,6 +32469,7 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; +// --- START parser Error class chunk --- const parseErrorSourceCode = ` function parseError(str, hash, ExceptionClass) { if (hash.recoverable) { @@ -32407,8 +32486,11 @@ function parseError(str, hash, ExceptionClass) { } throw new ExceptionClass(str, hash); } -}`; // END of parseErrorSourceCode chunk +} +`; +// --- END of parseErrorSourceCode chunk --- +chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -32420,123 +32502,125 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, +const define_parser_APIs_1 = ` + TERROR: 2, + EOF: 1, - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } - else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // An example of this may be where a rule's action code contains a call like this: // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. + // parser.getSymbolName(#$) // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [ - this.state_descriptions_[state] - ]; + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless \`do_not_describe\` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. } } - return tokenset; } - }; -} + return tokenset; + } +`; +// --- END of define_parser_APIs_1 chunk --- -var api_set = define_parser_APIs_1(); +var api_set = (new Function('', 'return { ' + define_parser_APIs_1 + ' };'))(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- -parser.parse = `function parse(input, parseParams) { +parser.parse = ` +function parse(input, parseParams) { var self = this; var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage) var sstack = new Array(128); // state stack: stores states (column storage) @@ -32702,7 +32786,11 @@ parser.parse = `function parse(input, parseParams) { } else { re1 = new XRegExp(' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": ', 'g'); } - js = JSON.stringify(obj, null, 2).replace(re1, ' $1: ').replace(/[\\n\\s]+/g, ' '); + js = JSON.stringify(obj, null, 2) + .replace(re1, ' $1: ') + .replace(/[\\n\\s]+/g, ' ') + // shorten yylloc object dumps too: + .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, '{L/C: ($1,$2)..($3,$4)'); } catch (ex) { js = String(obj); } @@ -32770,8 +32858,7 @@ parser.parse = `function parse(input, parseParams) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -33422,16 +33509,18 @@ parser.parse = `function parse(input, parseParams) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); + if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } - if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); // Protect against overly blunt userland \`parseError\` code which *sets* // the \`recoverable\` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -34007,13 +34096,12 @@ parser.parse = `function parse(input, parseParams) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -34021,7 +34109,8 @@ parser.parse = `function parse(input, parseParams) { } // /finally return retval; -}`; +} +`; // --- END parser kernel --- @@ -34070,7 +34159,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function (productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -34190,7 +34279,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -34206,7 +34295,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -34217,7 +34306,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -34245,7 +34334,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { @@ -34587,11 +34676,11 @@ Jison.Parser = Parser; var rmCommonWS = helpers.rmCommonWS; var mkIdentifier = helpers.mkIdentifier; -assert(Jison); -assert(typeof Jison.prettyPrint === 'function'); -assert(Jison.defaultJisonOptions); -assert(typeof Jison.mkStdOptions === 'function'); -assert(typeof Jison.Generator === 'function'); +assert$1(Jison); +assert$1(typeof Jison.prettyPrint === 'function'); +assert$1(Jison.defaultJisonOptions); +assert$1(typeof Jison.mkStdOptions === 'function'); +assert$1(typeof Jison.Generator === 'function'); var version = '0.6.1-215'; diff --git a/dist/cli-es6.js b/dist/cli-es6.js index cb30fc5c0..1846a5101 100644 --- a/dist/cli-es6.js +++ b/dist/cli-es6.js @@ -4,7 +4,7 @@ import fs from 'fs'; import path from 'path'; import recast from '@gerhobbelt/recast'; -import assert from 'assert'; +import assert$1 from 'assert'; import XRegExp from '@gerhobbelt/xregexp'; import json5 from '@gerhobbelt/json5'; import astUtils from '@gerhobbelt/ast-util'; @@ -165,6 +165,16 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -271,6 +281,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -315,13 +326,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -400,15 +411,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -681,10 +702,7 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1227,7 +1245,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1277,7 +1296,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1435,104 +1454,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4499,14 +4521,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4612,8 +4634,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -5231,7 +5252,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -5241,13 +5261,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5887,13 +5910,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5906,7 +5928,7 @@ yyError: 1 }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7536,7 +7558,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9184,7 +9205,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -9198,7 +9219,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -9207,7 +9228,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9396,7 +9417,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9665,9 +9686,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9820,8 +9841,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9836,7 +9857,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9959,6 +9980,14 @@ var version$2 = '0.6.1-215'; // require('./package. +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -10150,7 +10179,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -10158,7 +10187,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -10239,6 +10268,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10385,7 +10415,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10442,7 +10472,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10497,7 +10527,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10543,7 +10573,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10634,7 +10664,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10671,7 +10701,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10739,7 +10769,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10786,7 +10816,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10999,7 +11029,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -11028,9 +11058,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -11097,11 +11129,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -11112,7 +11144,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -11122,7 +11154,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -11135,8 +11167,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -11147,8 +11179,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12458,6 +12490,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$3` return ${getRegExpLexerPrototype()}; `))(); @@ -12569,6 +12602,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12727,6 +12761,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12799,9 +12834,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12845,8 +12880,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -13230,7 +13265,7 @@ RegExpLexer.camelCase = helpers.camelCase; RegExpLexer.mkIdentifier = mkIdentifier$4; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13761,7 +13796,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -13811,7 +13847,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13853,104 +13889,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 11, @@ -14903,13 +14942,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -14921,7 +14959,7 @@ parse: function parse(input) { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17093,10 +17131,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -17639,7 +17674,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -17689,7 +17725,7 @@ var parser$2 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -17841,104 +17877,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } + + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ s$1, @@ -20984,14 +21023,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -21097,8 +21136,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -21716,7 +21754,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -21726,13 +21763,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -22372,13 +22412,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -22391,7 +22430,7 @@ yyError: 1 }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -24021,7 +24060,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -26046,6 +26084,14 @@ var version$1 = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -26067,6 +26113,7 @@ const defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -26094,7 +26141,7 @@ const defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -26464,8 +26511,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -26728,13 +26775,26 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -27030,21 +27090,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -27052,7 +27112,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -27065,12 +27125,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -27399,7 +27459,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens @@ -27422,7 +27482,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -27502,12 +27562,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -27536,8 +27596,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -27545,7 +27605,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } @@ -27778,8 +27838,8 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); var h = [ self.actionsAreAllDefault, self.actionsUseLocationAssignment, @@ -27811,7 +27871,8 @@ function mkParserFeatureHash(self) { self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, - self.options.defaultActionMode.join(','), + self.options.defaultActionMode, + self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, @@ -27822,11 +27883,15 @@ function mkParserFeatureHash(self) { self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, + self.options.moduleName, + self.options.parseParams, + self.options.ranges, + self.options.prettyCfg, '======================================', self.performAction, '======================================', ]; - return h.join(','); + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -27856,8 +27921,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include) @@ -27866,7 +27931,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -27932,8 +27997,7 @@ generator.buildProductionActions = function buildProductionActions() { function __b0rk_on_internal_failure(str) { var hash = yyparser.constructParseErrorInfo(str, null, null, false); - var r = yyparser.parseError(str, hash, yyparser.JisonParserError); - return r; + return yyparser.parseError(str, hash, yyparser.JisonParserError); } return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);` @@ -28058,8 +28122,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -28198,6 +28262,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch, }); } @@ -28209,12 +28274,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -28342,8 +28407,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -28529,7 +28594,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -28832,7 +28897,8 @@ generator.createLexer = function createLexer() { }; // no-op. implemented in debug mixin -generator.trace = function no_op_trace() { }; +generator.trace = (new Function('', 'function no_op_trace() { }\nreturn no_op_trace;'))(); +//generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -28926,20 +28992,27 @@ generator.reportGrammarInformation = function reportGrammarInformation() { }; +// --- START of debugTraceSrc chunk --- +const debugTraceSrc = ` +function debug_trace() { + if (typeof Jison !== 'undefined' && Jison.print) { + Jison.print.apply(null, arguments); + } else if (typeof print !== 'undefined') { + print.apply(null, arguments); + } else if (typeof console !== 'undefined' && console.log) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(''); // prevent \`%.\` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args + console.log.apply(null, args); + } +} +`; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: (new Function('', debugTraceSrc + ` + return debug_trace;`))(), beforeprocessGrammar: function () { this.trace('Processing grammar.'); }, @@ -28983,7 +29056,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -29033,7 +29106,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -29436,7 +29509,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -29580,7 +29653,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -30187,8 +30260,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS$1` @@ -30241,8 +30314,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS$1` @@ -30906,7 +30979,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -30914,7 +30987,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -31126,7 +31199,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -31140,7 +31213,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = (bprod.newg_states || []); @@ -31274,6 +31347,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -31373,7 +31447,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // // Options: // - // default action mode: ............. ${this.options.defaultActionMode.join(',')} + // default action mode: ............. ${JSON.stringify(this.options.defaultActionMode)} + // test-compile action mode: ........ ${JSON.stringify(this.options.testCompileActionCode)} // try..catch: ...................... ${!this.options.noTryCatch} // default resolve on conflict: ..... ${!this.options.noDefaultResolve} // on-demand look-ahead: ............ ${this.onDemandLookahead} @@ -31440,11 +31515,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { 'terminal_descriptions_: ' + descrLst : [] ).concat([ - String(define_parser_APIs_1) - .replace(/^[\s\S]+?return \{/, '') - .replace(/\};[s\r\n]+\}\s*$/, '') - .replace(/^ /mg, '') - .trim(), + define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode ]).concat( String(this.performAction).trim() !== '' ? @@ -31475,7 +31546,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -31491,8 +31562,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - -var prelude = `// See also: + const prelude = ` +// See also: // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508 // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility // with userland code which might access the derived class in a 'classic' way. @@ -31541,8 +31612,8 @@ if (typeof Object.setPrototypeOf === 'function') { JisonParserError.prototype = Object.create(Error.prototype); } JisonParserError.prototype.constructor = JisonParserError; -JisonParserError.prototype.name = 'JisonParserError';`; - +JisonParserError.prototype.name = 'JisonParserError'; +`; // --- END parser error class --- return { @@ -31571,6 +31642,18 @@ lrGeneratorMixin.generateTableCode0 = function (table, defaultActions, productio }; }; +// Function that extends an object with the given value for all given keys +// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } +var compressor1ObjectCode = ` +function x(k, v, o) { + o = o || {}; + for (var l = k.length; l--; ) { + o[k[l]] = v; + } + return o; +} +`; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -31661,7 +31744,7 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -31679,16 +31762,6 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio }; }; -// Function that extends an object with the given value for all given keys -// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } -function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--; ) { - o[k[l]] = v; - } - return o; -} - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -31810,10 +31883,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -31843,7 +31916,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -31884,8 +31957,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -31898,7 +31971,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -32067,7 +32140,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var productionsDef = analyzeTableForCompression(productions); - var bp_code_container = ` + const bp_code_container = ` // helper: reconstruct the productions[] table function bp(s) { var rv = []; @@ -32083,7 +32156,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bda_code_container = ` + const bda_code_container = ` // helper: reconstruct the defaultActions[] table function bda(s) { var rv = {}; @@ -32097,7 +32170,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bt_code_container = ` + const bt_code_container = ` // helper: reconstruct the 'goto' table function bt(s) { var rv = []; @@ -32137,7 +32210,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var c_s_u_code_container = ` + const c_s_u_code_container = ` // helper: runlength encoding with increment step: code, length: step (default step = 0) // \`this\` references an array function s(c, l, a) { @@ -32216,8 +32289,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -const commonjsMain = ` +const commonJsMain = ` function (args) { // When the parser comes with its own \`main\` function, then use that one: if (typeof exports.parser.main === 'function') { @@ -32242,9 +32317,11 @@ function (args) { rv = dst; } return dst; -}`; +} +`; +// --- END of commonJsMain chunk --- -const commonjsMainImports = ` +const commonJsMainImports = ` var fs = require('fs'); var path = require('path'); `; @@ -32313,6 +32390,7 @@ generatorMixin.createParser = function createParser() { `; var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -32320,37 +32398,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert(typeof p === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(typeof p.yy === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1(typeof p === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(typeof p.yy === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(typeof p.symbols_ === 'object'); - assert(typeof p.terminals_ === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(typeof p.symbols_ === 'object'); + assert$1(typeof p.terminals_ === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(typeof p.table === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(typeof p.table === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(typeof p.constructParseErrorInfo === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(typeof p.options === 'object'); - assert(typeof p.cleanupAfterParse === 'object'); - assert(typeof p.yyMergeLocationInfo === 'object'); - assert(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); + assert$1(typeof p.constructParseErrorInfo === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(typeof p.options === 'object'); + assert$1(typeof p.cleanupAfterParse === 'object'); + assert$1(typeof p.yyMergeLocationInfo === 'object'); + assert$1(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -32387,6 +32465,7 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; +// --- START parser Error class chunk --- const parseErrorSourceCode = ` function parseError(str, hash, ExceptionClass) { if (hash.recoverable) { @@ -32403,8 +32482,11 @@ function parseError(str, hash, ExceptionClass) { } throw new ExceptionClass(str, hash); } -}`; // END of parseErrorSourceCode chunk +} +`; +// --- END of parseErrorSourceCode chunk --- +chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -32416,123 +32498,125 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, +const define_parser_APIs_1 = ` + TERROR: 2, + EOF: 1, - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } - else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // An example of this may be where a rule's action code contains a call like this: // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. + // parser.getSymbolName(#$) // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [ - this.state_descriptions_[state] - ]; + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless \`do_not_describe\` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. } } - return tokenset; } - }; -} + return tokenset; + } +`; +// --- END of define_parser_APIs_1 chunk --- -var api_set = define_parser_APIs_1(); +var api_set = (new Function('', 'return { ' + define_parser_APIs_1 + ' };'))(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- -parser.parse = `function parse(input, parseParams) { +parser.parse = ` +function parse(input, parseParams) { var self = this; var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage) var sstack = new Array(128); // state stack: stores states (column storage) @@ -32698,7 +32782,11 @@ parser.parse = `function parse(input, parseParams) { } else { re1 = new XRegExp(' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": ', 'g'); } - js = JSON.stringify(obj, null, 2).replace(re1, ' $1: ').replace(/[\\n\\s]+/g, ' '); + js = JSON.stringify(obj, null, 2) + .replace(re1, ' $1: ') + .replace(/[\\n\\s]+/g, ' ') + // shorten yylloc object dumps too: + .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, '{L/C: ($1,$2)..($3,$4)'); } catch (ex) { js = String(obj); } @@ -32766,8 +32854,7 @@ parser.parse = `function parse(input, parseParams) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -33418,16 +33505,18 @@ parser.parse = `function parse(input, parseParams) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); + if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } - if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); // Protect against overly blunt userland \`parseError\` code which *sets* // the \`recoverable\` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -34003,13 +34092,12 @@ parser.parse = `function parse(input, parseParams) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -34017,7 +34105,8 @@ parser.parse = `function parse(input, parseParams) { } // /finally return retval; -}`; +} +`; // --- END parser kernel --- @@ -34066,7 +34155,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function (productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -34186,7 +34275,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -34202,7 +34291,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -34213,7 +34302,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -34241,7 +34330,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { @@ -34583,11 +34672,11 @@ Jison.Parser = Parser; var rmCommonWS = helpers.rmCommonWS; var mkIdentifier = helpers.mkIdentifier; -assert(Jison); -assert(typeof Jison.prettyPrint === 'function'); -assert(Jison.defaultJisonOptions); -assert(typeof Jison.mkStdOptions === 'function'); -assert(typeof Jison.Generator === 'function'); +assert$1(Jison); +assert$1(typeof Jison.prettyPrint === 'function'); +assert$1(Jison.defaultJisonOptions); +assert$1(typeof Jison.mkStdOptions === 'function'); +assert$1(typeof Jison.Generator === 'function'); var version = '0.6.1-215'; diff --git a/dist/cli-umd-es5.js b/dist/cli-umd-es5.js index ad8b8f0ab..60a48766d 100644 --- a/dist/cli-umd-es5.js +++ b/dist/cli-umd-es5.js @@ -111,14 +111,14 @@ var _templateObject = _taggedTemplateLiteral(['\n There\'s an error in yo function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } (function (global, factory) { - (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('@gerhobbelt/ast-util'), require('process'), require('@gerhobbelt/nomnom')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5', '@gerhobbelt/ast-util', 'process', '@gerhobbelt/nomnom'], factory) : global['jison-cli'] = factory(global.fs, global.path, global.recast, global.assert, global.XRegExp, global.json5, global.astUtils, global.process$1, global.nomnom); -})(undefined, function (fs, path, recast, assert, XRegExp, json5, astUtils, process$1, nomnom) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('@gerhobbelt/ast-util'), require('process'), require('@gerhobbelt/nomnom')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5', '@gerhobbelt/ast-util', 'process', '@gerhobbelt/nomnom'], factory) : global['jison-cli'] = factory(global.fs, global.path, global.recast, global.assert$1, global.XRegExp, global.json5, global.astUtils, global.process$1, global.nomnom); +})(undefined, function (fs, path, recast, assert$1, XRegExp, json5, astUtils, process$1, nomnom) { 'use strict'; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; - assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; + assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; astUtils = astUtils && astUtils.hasOwnProperty('default') ? astUtils['default'] : astUtils; @@ -275,6 +275,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -365,6 +372,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -404,13 +412,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi //import astUtils from '@gerhobbelt/ast-util'; - assert(recast); + assert$1(recast); var types = recast.types; - assert(types); + assert$1(types); var namedTypes = types.namedTypes; - assert(namedTypes); + assert$1(namedTypes); var b = types.builders; - assert(b); + assert$1(b); // //assert(astUtils); @@ -474,15 +482,24 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi checkActionBlock: checkActionBlock }; + function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -754,10 +771,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var Set = typal.construct(setMixin); - // hack: - var assert$1; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1283,7 +1297,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2872,14 +2887,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2968,8 +2983,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3524,14 +3538,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -4027,13 +4042,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -4046,7 +4061,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5645,7 +5660,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6961,7 +6975,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6975,7 +6989,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6984,7 +6998,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -7168,7 +7182,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7434,9 +7448,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7586,8 +7600,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7602,7 +7616,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7716,6 +7730,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var version$2 = '0.6.1-215'; // require('./package.json').version; + function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7901,7 +7922,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7909,7 +7930,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7990,6 +8011,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -8130,7 +8152,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -8187,7 +8209,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -8242,7 +8264,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -8287,7 +8309,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8378,7 +8400,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8415,7 +8437,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8480,7 +8502,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8527,7 +8549,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8660,7 +8682,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8684,6 +8706,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8750,11 +8773,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8765,14 +8788,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8785,8 +8808,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8797,8 +8820,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8891,6 +8914,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // --- END lexer kernel --- } + chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS$3(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8954,6 +8978,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -9112,6 +9137,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -9178,9 +9204,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -9215,8 +9241,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -9317,7 +9343,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi RegExpLexer.mkIdentifier = mkIdentifier$4; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -9831,7 +9857,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -10593,13 +10620,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -10611,7 +10638,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -12702,10 +12729,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return rv; } - // hack: - var assert$2; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13231,7 +13255,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -14863,14 +14888,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -14959,8 +14984,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -15515,14 +15539,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -16018,13 +16043,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -16037,7 +16062,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17636,7 +17661,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -19274,6 +19298,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var devDebug = 0; + function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -19295,6 +19326,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -19322,7 +19354,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -19693,8 +19725,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -19955,13 +19987,26 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -20253,21 +20298,21 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -20275,7 +20320,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -20288,12 +20333,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -20614,7 +20659,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens // as used in a rule like this: `rule: A ' ' B;` which should produce 3 tokens for the @@ -20636,7 +20681,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -20716,12 +20761,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -20750,8 +20795,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -20759,7 +20804,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } else { @@ -20947,10 +20992,10 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); - var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode.join(','), self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, '======================================', self.performAction, '======================================']; - return h.join(','); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); + var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode, self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, self.options.moduleName, self.options.parseParams, self.options.ranges, self.options.prettyCfg, '======================================', self.performAction, '======================================']; + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -20978,8 +21023,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include).replace(/#([^#\s\r\n]+)#/g, function (_, sym) { @@ -20987,7 +21032,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -21028,7 +21073,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (missingActions.length) { console.warn("WARNING: missing actions for states: ", missingActions); - actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n var r = yyparser.parseError(str, hash, yyparser.JisonParserError);\n return r;\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); + actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n return yyparser.parseError(str, hash, yyparser.JisonParserError);\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); } actions.push('}'); @@ -21139,8 +21184,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -21281,6 +21326,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch }); } @@ -21292,12 +21338,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -21412,8 +21458,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -21593,7 +21639,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -21885,7 +21931,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; // no-op. implemented in debug mixin - generator.trace = function no_op_trace() {}; + generator.trace = new Function('', 'function no_op_trace() { }\nreturn no_op_trace;')(); + //generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -21979,20 +22026,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi this.warn('\n'); }; + // --- START of debugTraceSrc chunk --- + var debugTraceSrc = '\nfunction debug_trace() {\n if (typeof Jison !== \'undefined\' && Jison.print) {\n Jison.print.apply(null, arguments);\n } else if (typeof print !== \'undefined\') {\n print.apply(null, arguments);\n } else if (typeof console !== \'undefined\' && console.log) {\n var args = Array.prototype.slice.call(arguments, 0);\n args.unshift(\'\'); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args\n console.log.apply(null, args);\n }\n}\n'; + // --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: new Function('', debugTraceSrc + '\n return debug_trace;')(), beforeprocessGrammar: function beforeprocessGrammar() { this.trace('Processing grammar.'); }, @@ -22034,7 +22075,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -22084,7 +22125,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -22491,7 +22532,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -22635,7 +22676,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -22847,8 +22888,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS$1(_templateObject96, moduleImportsAsCode, moduleNameAsCode.trim())); exportMain = 'main: yyExecMain,'; @@ -22867,8 +22908,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS$1(_templateObject99, moduleImportsAsCode, moduleNameAsCode.trim()); } @@ -23418,7 +23459,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -23426,7 +23467,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -23630,7 +23671,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -23644,7 +23685,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = bprod.newg_states || []; @@ -23778,6 +23819,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -23870,12 +23912,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // produce a hash lookup table from the terminal set exportDest.terminalTable = produceTerminalTable(this.terminals_); - var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + this.options.defaultActionMode.join(',') + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; - moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([String(define_parser_APIs_1).replace(/^[\s\S]+?return \{/, '').replace(/\};[s\r\n]+\}\s*$/, '').replace(/^ /mg, '').trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); + var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + JSON.stringify(this.options.defaultActionMode) + '\n // test-compile action mode: ........ ' + JSON.stringify(this.options.testCompileActionCode) + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; + moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -23888,9 +23930,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - - var prelude = '// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';'; - + var prelude = '\n// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';\n'; // --- END parser error class --- return { @@ -23919,6 +23959,10 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; }; + // Function that extends an object with the given value for all given keys + // e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } + var compressor1ObjectCode = '\nfunction x(k, v, o) {\n o = o || {};\n for (var l = k.length; l--; ) {\n o[k[l]] = v;\n }\n return o;\n}\n'; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -24011,7 +24055,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -24029,16 +24073,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; }; - // Function that extends an object with the given value for all given keys - // e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } - function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--;) { - o[k[l]] = v; - } - return o; - } - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -24156,10 +24190,10 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -24186,7 +24220,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -24225,8 +24259,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -24239,7 +24273,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot === 'undefined' ? 'undefined' : _typeof(slot)) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -24408,10 +24442,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; }; + // --- START of commonJsMain chunk --- + // // default main method for generated commonjs modules - var commonjsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}'; + var commonJsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}\n'; + // --- END of commonJsMain chunk --- - var commonjsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; + var commonJsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; // debug mixin for LR parser generators @@ -24462,6 +24499,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var sourcecode = rmCommonWS$1(_templateObject101, sourceCodeDef.init, sourceCodeDef.src); var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -24469,37 +24507,37 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throwErrorOnCompileFailure: true }), "parser"); - assert((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(_typeof(p.yy) === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(_typeof(p.yy) === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(_typeof(p.symbols_) === 'object'); - assert(_typeof(p.terminals_) === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(_typeof(p.symbols_) === 'object'); + assert$1(_typeof(p.terminals_) === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(_typeof(p.table) === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(_typeof(p.table) === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(_typeof(p.constructParseErrorInfo) === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(_typeof(p.options) === 'object'); - assert(_typeof(p.cleanupAfterParse) === 'object'); - assert(_typeof(p.yyMergeLocationInfo) === 'object'); - assert(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); + assert$1(_typeof(p.constructParseErrorInfo) === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(_typeof(p.options) === 'object'); + assert$1(_typeof(p.cleanupAfterParse) === 'object'); + assert$1(_typeof(p.yyMergeLocationInfo) === 'object'); + assert$1(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -24536,8 +24574,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parser.warn = generator.warn; parser.error = generator.error; - var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}'; // END of parseErrorSourceCode chunk + // --- START parser Error class chunk --- + var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}\n'; + // --- END of parseErrorSourceCode chunk --- + chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -24548,119 +24589,20 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return lexer; }; - // wrapper function so we easily stringify the APIs defined inside to code *with comments* + // --- START parser API def chunk --- + // + // One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: - function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, - - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } - - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, - - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. - // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. - // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. - // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } - } - } - return tokenset; - } - }; - } + var define_parser_APIs_1 = '\n TERROR: 2,\n EOF: 1,\n\n // internals: defined here so the object *structure* doesn\'t get modified by parse() et al,\n // thus helping JIT compilers like Chrome V8.\n originalQuoteName: null,\n originalParseError: null,\n cleanupAfterParse: null,\n constructParseErrorInfo: null,\n yyMergeLocationInfo: null,\n\n __reentrant_call_depth: 0, // INTERNAL USE ONLY\n __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n\n // APIs which will be set up depending on user action code analysis:\n //yyRecovering: 0,\n //yyErrOk: 0,\n //yyClearIn: 0,\n\n // Helper APIs\n // -----------\n\n // Helper function which can be overridden by user code later on: put suitable quotes around\n // literal IDs in a description string.\n quoteName: function parser_quoteName(id_str) {\n return \'"\' + id_str + \'"\';\n },\n\n // Return the name of the given symbol (terminal or non-terminal) as a string, when available.\n //\n // Return NULL when the symbol is unknown to the parser.\n getSymbolName: function parser_getSymbolName(symbol) {\n if (this.terminals_[symbol]) {\n return this.terminals_[symbol];\n }\n\n // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up.\n //\n // An example of this may be where a rule\'s action code contains a call like this:\n //\n // parser.getSymbolName(#$)\n //\n // to obtain a human-readable name of the current grammar rule.\n var s = this.symbols_;\n for (var key in s) {\n if (s[key] === symbol) {\n return key;\n }\n }\n return null;\n },\n\n // Return a more-or-less human-readable description of the given symbol, when available,\n // or the symbol itself, serving as its own \'description\' for lack of something better to serve up.\n //\n // Return NULL when the symbol is unknown to the parser.\n describeSymbol: function parser_describeSymbol(symbol) {\n if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) {\n return this.terminal_descriptions_[symbol];\n }\n else if (symbol === this.EOF) {\n return \'end of input\';\n }\n var id = this.getSymbolName(symbol);\n if (id) {\n return this.quoteName(id);\n }\n return null;\n },\n\n // Produce a (more or less) human-readable list of expected tokens at the point of failure.\n //\n // The produced list may contain token or token set descriptions instead of the tokens\n // themselves to help turning this output into something that easier to read by humans\n // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*,\n // expected terminals and nonterminals is produced.\n //\n // The returned list (array) will not contain any duplicate entries.\n collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) {\n var TERROR = this.TERROR;\n var tokenset = [];\n var check = {};\n // Has this (error?) state been outfitted with a custom expectations description text for human consumption?\n // If so, use that one instead of the less palatable token set.\n if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) {\n return [\n this.state_descriptions_[state]\n ];\n }\n for (var p in this.table[state]) {\n p = +p;\n if (p !== TERROR) {\n var d = do_not_describe ? p : this.describeSymbol(p);\n if (d && !check[d]) {\n tokenset.push(d);\n check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries.\n }\n }\n }\n return tokenset;\n }\n'; + // --- END of define_parser_APIs_1 chunk --- - var api_set = define_parser_APIs_1(); + var api_set = new Function('', 'return { ' + define_parser_APIs_1 + ' };')(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- - parser.parse = 'function parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2).replace(re1, \' $1: \').replace(/[\\n\\s]+/g, \' \');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n var r = this.parseError(str, hash, this.JisonParserError);\n return r;\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n else {\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}'; + parser.parse = '\nfunction parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2)\n .replace(re1, \' $1: \')\n .replace(/[\\n\\s]+/g, \' \')\n // shorten yylloc object dumps too:\n .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, \'{L/C: ($1,$2)..($3,$4)\');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n return this.parseError(str, hash, this.JisonParserError);\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}\n'; // --- END parser kernel --- @@ -24709,7 +24651,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi DEBUG: false, go_: function go_(productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -24824,7 +24766,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -24840,7 +24782,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -24851,7 +24793,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -24879,7 +24821,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { @@ -25220,11 +25162,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var rmCommonWS = helpers.rmCommonWS; var mkIdentifier = helpers.mkIdentifier; - assert(Jison); - assert(typeof Jison.prettyPrint === 'function'); - assert(Jison.defaultJisonOptions); - assert(typeof Jison.mkStdOptions === 'function'); - assert(typeof Jison.Generator === 'function'); + assert$1(Jison); + assert$1(typeof Jison.prettyPrint === 'function'); + assert$1(Jison.defaultJisonOptions); + assert$1(typeof Jison.mkStdOptions === 'function'); + assert$1(typeof Jison.Generator === 'function'); var version = '0.6.1-215'; diff --git a/dist/cli-umd.js b/dist/cli-umd.js index 2e5617656..fc16e9306 100644 --- a/dist/cli-umd.js +++ b/dist/cli-umd.js @@ -4,13 +4,13 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('@gerhobbelt/ast-util'), require('process'), require('@gerhobbelt/nomnom')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5', '@gerhobbelt/ast-util', 'process', '@gerhobbelt/nomnom'], factory) : - (global['jison-cli'] = factory(global.fs,global.path,global.recast,global.assert,global.XRegExp,global.json5,global.astUtils,global.process$1,global.nomnom)); -}(this, (function (fs,path,recast,assert,XRegExp,json5,astUtils,process$1,nomnom) { 'use strict'; + (global['jison-cli'] = factory(global.fs,global.path,global.recast,global.assert$1,global.XRegExp,global.json5,global.astUtils,global.process$1,global.nomnom)); +}(this, (function (fs,path,recast,assert$1,XRegExp,json5,astUtils,process$1,nomnom) { 'use strict'; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; -assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; +assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; astUtils = astUtils && astUtils.hasOwnProperty('default') ? astUtils['default'] : astUtils; @@ -171,6 +171,16 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -277,6 +287,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -321,13 +332,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -406,15 +417,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -687,10 +708,7 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1233,7 +1251,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1283,7 +1302,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1441,104 +1460,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4505,14 +4527,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4618,8 +4640,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -5237,7 +5258,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -5247,13 +5267,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5893,13 +5916,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5912,7 +5934,7 @@ yyError: 1 }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7542,7 +7564,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9190,7 +9211,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -9204,7 +9225,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -9213,7 +9234,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9402,7 +9423,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9671,9 +9692,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9826,8 +9847,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9842,7 +9863,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9965,6 +9986,14 @@ var version$2 = '0.6.1-215'; // require('./package. +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -10156,7 +10185,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -10164,7 +10193,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -10245,6 +10274,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10391,7 +10421,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10448,7 +10478,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10503,7 +10533,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10549,7 +10579,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10640,7 +10670,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10677,7 +10707,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10745,7 +10775,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10792,7 +10822,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -11005,7 +11035,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -11034,9 +11064,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -11103,11 +11135,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -11118,7 +11150,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -11128,7 +11160,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -11141,8 +11173,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -11153,8 +11185,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12464,6 +12496,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$3` return ${getRegExpLexerPrototype()}; `))(); @@ -12575,6 +12608,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12733,6 +12767,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12805,9 +12840,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12851,8 +12886,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -13236,7 +13271,7 @@ RegExpLexer.camelCase = helpers.camelCase; RegExpLexer.mkIdentifier = mkIdentifier$4; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13767,7 +13802,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -13817,7 +13853,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13859,104 +13895,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 11, @@ -14909,13 +14948,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -14927,7 +14965,7 @@ parse: function parse(input) { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17099,10 +17137,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -17645,7 +17680,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -17695,7 +17731,7 @@ var parser$2 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -17847,104 +17883,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } + + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ s$1, @@ -20990,14 +21029,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -21103,8 +21142,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -21722,7 +21760,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -21732,13 +21769,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -22378,13 +22418,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -22397,7 +22436,7 @@ yyError: 1 }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -24027,7 +24066,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -26052,6 +26090,14 @@ var version$1 = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -26073,6 +26119,7 @@ const defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -26100,7 +26147,7 @@ const defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -26470,8 +26517,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -26734,13 +26781,26 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -27036,21 +27096,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -27058,7 +27118,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -27071,12 +27131,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -27405,7 +27465,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens @@ -27428,7 +27488,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -27508,12 +27568,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -27542,8 +27602,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -27551,7 +27611,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } @@ -27784,8 +27844,8 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); var h = [ self.actionsAreAllDefault, self.actionsUseLocationAssignment, @@ -27817,7 +27877,8 @@ function mkParserFeatureHash(self) { self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, - self.options.defaultActionMode.join(','), + self.options.defaultActionMode, + self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, @@ -27828,11 +27889,15 @@ function mkParserFeatureHash(self) { self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, + self.options.moduleName, + self.options.parseParams, + self.options.ranges, + self.options.prettyCfg, '======================================', self.performAction, '======================================', ]; - return h.join(','); + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -27862,8 +27927,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include) @@ -27872,7 +27937,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -27938,8 +28003,7 @@ generator.buildProductionActions = function buildProductionActions() { function __b0rk_on_internal_failure(str) { var hash = yyparser.constructParseErrorInfo(str, null, null, false); - var r = yyparser.parseError(str, hash, yyparser.JisonParserError); - return r; + return yyparser.parseError(str, hash, yyparser.JisonParserError); } return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);` @@ -28064,8 +28128,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -28204,6 +28268,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch, }); } @@ -28215,12 +28280,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -28348,8 +28413,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -28535,7 +28600,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -28838,7 +28903,8 @@ generator.createLexer = function createLexer() { }; // no-op. implemented in debug mixin -generator.trace = function no_op_trace() { }; +generator.trace = (new Function('', 'function no_op_trace() { }\nreturn no_op_trace;'))(); +//generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -28932,20 +28998,27 @@ generator.reportGrammarInformation = function reportGrammarInformation() { }; +// --- START of debugTraceSrc chunk --- +const debugTraceSrc = ` +function debug_trace() { + if (typeof Jison !== 'undefined' && Jison.print) { + Jison.print.apply(null, arguments); + } else if (typeof print !== 'undefined') { + print.apply(null, arguments); + } else if (typeof console !== 'undefined' && console.log) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(''); // prevent \`%.\` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args + console.log.apply(null, args); + } +} +`; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: (new Function('', debugTraceSrc + ` + return debug_trace;`))(), beforeprocessGrammar: function () { this.trace('Processing grammar.'); }, @@ -28989,7 +29062,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -29039,7 +29112,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -29442,7 +29515,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -29586,7 +29659,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -30193,8 +30266,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS$1` @@ -30247,8 +30320,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS$1` @@ -30912,7 +30985,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -30920,7 +30993,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -31132,7 +31205,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -31146,7 +31219,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = (bprod.newg_states || []); @@ -31280,6 +31353,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -31379,7 +31453,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // // Options: // - // default action mode: ............. ${this.options.defaultActionMode.join(',')} + // default action mode: ............. ${JSON.stringify(this.options.defaultActionMode)} + // test-compile action mode: ........ ${JSON.stringify(this.options.testCompileActionCode)} // try..catch: ...................... ${!this.options.noTryCatch} // default resolve on conflict: ..... ${!this.options.noDefaultResolve} // on-demand look-ahead: ............ ${this.onDemandLookahead} @@ -31446,11 +31521,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { 'terminal_descriptions_: ' + descrLst : [] ).concat([ - String(define_parser_APIs_1) - .replace(/^[\s\S]+?return \{/, '') - .replace(/\};[s\r\n]+\}\s*$/, '') - .replace(/^ /mg, '') - .trim(), + define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode ]).concat( String(this.performAction).trim() !== '' ? @@ -31481,7 +31552,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -31497,8 +31568,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - -var prelude = `// See also: + const prelude = ` +// See also: // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508 // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility // with userland code which might access the derived class in a 'classic' way. @@ -31547,8 +31618,8 @@ if (typeof Object.setPrototypeOf === 'function') { JisonParserError.prototype = Object.create(Error.prototype); } JisonParserError.prototype.constructor = JisonParserError; -JisonParserError.prototype.name = 'JisonParserError';`; - +JisonParserError.prototype.name = 'JisonParserError'; +`; // --- END parser error class --- return { @@ -31577,6 +31648,18 @@ lrGeneratorMixin.generateTableCode0 = function (table, defaultActions, productio }; }; +// Function that extends an object with the given value for all given keys +// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } +var compressor1ObjectCode = ` +function x(k, v, o) { + o = o || {}; + for (var l = k.length; l--; ) { + o[k[l]] = v; + } + return o; +} +`; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -31667,7 +31750,7 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -31685,16 +31768,6 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio }; }; -// Function that extends an object with the given value for all given keys -// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } -function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--; ) { - o[k[l]] = v; - } - return o; -} - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -31816,10 +31889,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -31849,7 +31922,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -31890,8 +31963,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -31904,7 +31977,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -32073,7 +32146,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var productionsDef = analyzeTableForCompression(productions); - var bp_code_container = ` + const bp_code_container = ` // helper: reconstruct the productions[] table function bp(s) { var rv = []; @@ -32089,7 +32162,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bda_code_container = ` + const bda_code_container = ` // helper: reconstruct the defaultActions[] table function bda(s) { var rv = {}; @@ -32103,7 +32176,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bt_code_container = ` + const bt_code_container = ` // helper: reconstruct the 'goto' table function bt(s) { var rv = []; @@ -32143,7 +32216,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var c_s_u_code_container = ` + const c_s_u_code_container = ` // helper: runlength encoding with increment step: code, length: step (default step = 0) // \`this\` references an array function s(c, l, a) { @@ -32222,8 +32295,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -const commonjsMain = ` +const commonJsMain = ` function (args) { // When the parser comes with its own \`main\` function, then use that one: if (typeof exports.parser.main === 'function') { @@ -32248,9 +32323,11 @@ function (args) { rv = dst; } return dst; -}`; +} +`; +// --- END of commonJsMain chunk --- -const commonjsMainImports = ` +const commonJsMainImports = ` var fs = require('fs'); var path = require('path'); `; @@ -32319,6 +32396,7 @@ generatorMixin.createParser = function createParser() { `; var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -32326,37 +32404,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert(typeof p === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(typeof p.yy === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1(typeof p === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(typeof p.yy === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(typeof p.symbols_ === 'object'); - assert(typeof p.terminals_ === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(typeof p.symbols_ === 'object'); + assert$1(typeof p.terminals_ === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(typeof p.table === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(typeof p.table === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(typeof p.constructParseErrorInfo === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(typeof p.options === 'object'); - assert(typeof p.cleanupAfterParse === 'object'); - assert(typeof p.yyMergeLocationInfo === 'object'); - assert(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); + assert$1(typeof p.constructParseErrorInfo === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(typeof p.options === 'object'); + assert$1(typeof p.cleanupAfterParse === 'object'); + assert$1(typeof p.yyMergeLocationInfo === 'object'); + assert$1(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -32393,6 +32471,7 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; +// --- START parser Error class chunk --- const parseErrorSourceCode = ` function parseError(str, hash, ExceptionClass) { if (hash.recoverable) { @@ -32409,8 +32488,11 @@ function parseError(str, hash, ExceptionClass) { } throw new ExceptionClass(str, hash); } -}`; // END of parseErrorSourceCode chunk +} +`; +// --- END of parseErrorSourceCode chunk --- +chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -32422,123 +32504,125 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, +const define_parser_APIs_1 = ` + TERROR: 2, + EOF: 1, - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } - else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // An example of this may be where a rule's action code contains a call like this: // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. + // parser.getSymbolName(#$) // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [ - this.state_descriptions_[state] - ]; + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless \`do_not_describe\` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. } } - return tokenset; } - }; -} + return tokenset; + } +`; +// --- END of define_parser_APIs_1 chunk --- -var api_set = define_parser_APIs_1(); +var api_set = (new Function('', 'return { ' + define_parser_APIs_1 + ' };'))(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- -parser.parse = `function parse(input, parseParams) { +parser.parse = ` +function parse(input, parseParams) { var self = this; var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage) var sstack = new Array(128); // state stack: stores states (column storage) @@ -32704,7 +32788,11 @@ parser.parse = `function parse(input, parseParams) { } else { re1 = new XRegExp(' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": ', 'g'); } - js = JSON.stringify(obj, null, 2).replace(re1, ' $1: ').replace(/[\\n\\s]+/g, ' '); + js = JSON.stringify(obj, null, 2) + .replace(re1, ' $1: ') + .replace(/[\\n\\s]+/g, ' ') + // shorten yylloc object dumps too: + .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, '{L/C: ($1,$2)..($3,$4)'); } catch (ex) { js = String(obj); } @@ -32772,8 +32860,7 @@ parser.parse = `function parse(input, parseParams) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -33424,16 +33511,18 @@ parser.parse = `function parse(input, parseParams) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); + if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } - if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); // Protect against overly blunt userland \`parseError\` code which *sets* // the \`recoverable\` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -34009,13 +34098,12 @@ parser.parse = `function parse(input, parseParams) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -34023,7 +34111,8 @@ parser.parse = `function parse(input, parseParams) { } // /finally return retval; -}`; +} +`; // --- END parser kernel --- @@ -34072,7 +34161,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function (productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -34192,7 +34281,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -34208,7 +34297,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -34219,7 +34308,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -34247,7 +34336,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { @@ -34589,11 +34678,11 @@ Jison.Parser = Parser; var rmCommonWS = helpers.rmCommonWS; var mkIdentifier = helpers.mkIdentifier; -assert(Jison); -assert(typeof Jison.prettyPrint === 'function'); -assert(Jison.defaultJisonOptions); -assert(typeof Jison.mkStdOptions === 'function'); -assert(typeof Jison.Generator === 'function'); +assert$1(Jison); +assert$1(typeof Jison.prettyPrint === 'function'); +assert$1(Jison.defaultJisonOptions); +assert$1(typeof Jison.mkStdOptions === 'function'); +assert$1(typeof Jison.Generator === 'function'); var version = '0.6.1-215'; diff --git a/dist/jison-cjs-es5.js b/dist/jison-cjs-es5.js index 23786a121..193b5b766 100644 --- a/dist/jison-cjs-es5.js +++ b/dist/jison-cjs-es5.js @@ -113,7 +113,7 @@ function _interopDefault(ex) { var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var json5 = _interopDefault(require('@gerhobbelt/json5')); var astUtils = _interopDefault(require('@gerhobbelt/ast-util')); @@ -268,6 +268,13 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -358,6 +365,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -397,13 +405,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -467,15 +475,24 @@ var parse2AST = { checkActionBlock: checkActionBlock }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -747,10 +764,7 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1276,7 +1290,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2865,14 +2880,14 @@ var parser$1 = { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2961,8 +2976,7 @@ var parser$1 = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3517,14 +3531,15 @@ var parser$1 = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -4020,13 +4035,13 @@ var parser$1 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -4039,7 +4054,7 @@ var parser$1 = { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5638,7 +5653,6 @@ var lexer = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6954,7 +6968,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6968,7 +6982,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6977,7 +6991,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -7161,7 +7175,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7427,9 +7441,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7579,8 +7593,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7595,7 +7609,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7709,6 +7723,13 @@ var code_exec$2 = helpers.exec; var version$1 = '0.6.1-215'; // require('./package.json').version; +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7894,7 +7915,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7902,7 +7923,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7983,6 +8004,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -8123,7 +8145,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -8180,7 +8202,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -8235,7 +8257,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -8280,7 +8302,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8371,7 +8393,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8408,7 +8430,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8473,7 +8495,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8520,7 +8542,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8653,7 +8675,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8677,6 +8699,7 @@ function RegExpLexer(dict, input, tokens, build_options) { var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8743,11 +8766,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8758,14 +8781,14 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8778,8 +8801,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8790,8 +8813,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8884,6 +8907,7 @@ function getRegExpLexerPrototype() { // --- END lexer kernel --- } +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS$2(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8947,6 +8971,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -9105,6 +9130,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -9171,9 +9197,9 @@ function generateModuleBody(opt) { protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -9208,8 +9234,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -9310,7 +9336,7 @@ RegExpLexer.camelCase = helpers.camelCase; RegExpLexer.mkIdentifier = mkIdentifier$3; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -9824,7 +9850,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -10586,13 +10613,13 @@ var parser$3 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -10604,7 +10631,7 @@ var parser$3 = { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -12695,10 +12722,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13224,7 +13248,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -14856,14 +14881,14 @@ var parser$2 = { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -14952,8 +14977,7 @@ var parser$2 = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -15508,14 +15532,15 @@ var parser$2 = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -16011,13 +16036,13 @@ var parser$2 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -16030,7 +16055,7 @@ var parser$2 = { }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17629,7 +17654,6 @@ var lexer$1 = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -19267,6 +19291,13 @@ var version = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -19288,6 +19319,7 @@ var defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -19315,7 +19347,7 @@ var defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -19686,8 +19718,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -19948,13 +19980,26 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -20246,21 +20291,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -20268,7 +20313,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -20281,12 +20326,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -20607,7 +20652,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens // as used in a rule like this: `rule: A ' ' B;` which should produce 3 tokens for the @@ -20629,7 +20674,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -20709,12 +20754,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -20743,8 +20788,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -20752,7 +20797,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } else { @@ -20940,10 +20985,10 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { } function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); - var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode.join(','), self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, '======================================', self.performAction, '======================================']; - return h.join(','); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); + var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode, self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, self.options.moduleName, self.options.parseParams, self.options.ranges, self.options.prettyCfg, '======================================', self.performAction, '======================================']; + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -20971,8 +21016,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include).replace(/#([^#\s\r\n]+)#/g, function (_, sym) { @@ -20980,7 +21025,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -21021,7 +21066,7 @@ generator.buildProductionActions = function buildProductionActions() { if (missingActions.length) { console.warn("WARNING: missing actions for states: ", missingActions); - actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n var r = yyparser.parseError(str, hash, yyparser.JisonParserError);\n return r;\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); + actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n return yyparser.parseError(str, hash, yyparser.JisonParserError);\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); } actions.push('}'); @@ -21132,8 +21177,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -21274,6 +21319,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch }); } @@ -21285,12 +21331,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -21405,8 +21451,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -21586,7 +21632,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -21878,7 +21924,8 @@ generator.createLexer = function createLexer() { }; // no-op. implemented in debug mixin -generator.trace = function no_op_trace() {}; +generator.trace = new Function('', 'function no_op_trace() { }\nreturn no_op_trace;')(); +//generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -21972,20 +22019,14 @@ generator.reportGrammarInformation = function reportGrammarInformation() { this.warn('\n'); }; +// --- START of debugTraceSrc chunk --- +var debugTraceSrc = '\nfunction debug_trace() {\n if (typeof Jison !== \'undefined\' && Jison.print) {\n Jison.print.apply(null, arguments);\n } else if (typeof print !== \'undefined\') {\n print.apply(null, arguments);\n } else if (typeof console !== \'undefined\' && console.log) {\n var args = Array.prototype.slice.call(arguments, 0);\n args.unshift(\'\'); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args\n console.log.apply(null, args);\n }\n}\n'; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: new Function('', debugTraceSrc + '\n return debug_trace;')(), beforeprocessGrammar: function beforeprocessGrammar() { this.trace('Processing grammar.'); }, @@ -22027,7 +22068,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -22077,7 +22118,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -22484,7 +22525,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -22628,7 +22669,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -22840,8 +22881,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS(_templateObject96, moduleImportsAsCode, moduleNameAsCode.trim())); exportMain = 'main: yyExecMain,'; @@ -22860,8 +22901,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS(_templateObject99, moduleImportsAsCode, moduleNameAsCode.trim()); } @@ -23411,7 +23452,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -23419,7 +23460,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -23623,7 +23664,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -23637,7 +23678,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = bprod.newg_states || []; @@ -23771,6 +23812,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -23863,12 +23905,12 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // produce a hash lookup table from the terminal set exportDest.terminalTable = produceTerminalTable(this.terminals_); - var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + this.options.defaultActionMode.join(',') + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; - moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([String(define_parser_APIs_1).replace(/^[\s\S]+?return \{/, '').replace(/\};[s\r\n]+\}\s*$/, '').replace(/^ /mg, '').trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); + var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + JSON.stringify(this.options.defaultActionMode) + '\n // test-compile action mode: ........ ' + JSON.stringify(this.options.testCompileActionCode) + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; + moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -23881,9 +23923,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - - var prelude = '// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';'; - + var prelude = '\n// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';\n'; // --- END parser error class --- return { @@ -23912,6 +23952,10 @@ lrGeneratorMixin.generateTableCode0 = function (table, defaultActions, productio }; }; +// Function that extends an object with the given value for all given keys +// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } +var compressor1ObjectCode = '\nfunction x(k, v, o) {\n o = o || {};\n for (var l = k.length; l--; ) {\n o[k[l]] = v;\n }\n return o;\n}\n'; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -24004,7 +24048,7 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -24022,16 +24066,6 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio }; }; -// Function that extends an object with the given value for all given keys -// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } -function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--;) { - o[k[l]] = v; - } - return o; -} - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -24149,10 +24183,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -24179,7 +24213,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -24218,8 +24252,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -24232,7 +24266,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot === 'undefined' ? 'undefined' : _typeof(slot)) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -24401,10 +24435,13 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -var commonjsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}'; +var commonJsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}\n'; +// --- END of commonJsMain chunk --- -var commonjsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; +var commonJsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; // debug mixin for LR parser generators @@ -24455,6 +24492,7 @@ generatorMixin.createParser = function createParser() { var sourcecode = rmCommonWS(_templateObject101, sourceCodeDef.init, sourceCodeDef.src); var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -24462,37 +24500,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(_typeof(p.yy) === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(_typeof(p.yy) === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(_typeof(p.symbols_) === 'object'); - assert(_typeof(p.terminals_) === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(_typeof(p.symbols_) === 'object'); + assert$1(_typeof(p.terminals_) === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(_typeof(p.table) === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(_typeof(p.table) === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(_typeof(p.constructParseErrorInfo) === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(_typeof(p.options) === 'object'); - assert(_typeof(p.cleanupAfterParse) === 'object'); - assert(_typeof(p.yyMergeLocationInfo) === 'object'); - assert(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); + assert$1(_typeof(p.constructParseErrorInfo) === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(_typeof(p.options) === 'object'); + assert$1(_typeof(p.cleanupAfterParse) === 'object'); + assert$1(_typeof(p.yyMergeLocationInfo) === 'object'); + assert$1(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -24529,8 +24567,11 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; -var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}'; // END of parseErrorSourceCode chunk +// --- START parser Error class chunk --- +var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}\n'; +// --- END of parseErrorSourceCode chunk --- +chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -24541,119 +24582,20 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti return lexer; }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, - - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } - - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, - - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. - // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. - // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. - // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } - } - } - return tokenset; - } - }; -} +var define_parser_APIs_1 = '\n TERROR: 2,\n EOF: 1,\n\n // internals: defined here so the object *structure* doesn\'t get modified by parse() et al,\n // thus helping JIT compilers like Chrome V8.\n originalQuoteName: null,\n originalParseError: null,\n cleanupAfterParse: null,\n constructParseErrorInfo: null,\n yyMergeLocationInfo: null,\n\n __reentrant_call_depth: 0, // INTERNAL USE ONLY\n __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n\n // APIs which will be set up depending on user action code analysis:\n //yyRecovering: 0,\n //yyErrOk: 0,\n //yyClearIn: 0,\n\n // Helper APIs\n // -----------\n\n // Helper function which can be overridden by user code later on: put suitable quotes around\n // literal IDs in a description string.\n quoteName: function parser_quoteName(id_str) {\n return \'"\' + id_str + \'"\';\n },\n\n // Return the name of the given symbol (terminal or non-terminal) as a string, when available.\n //\n // Return NULL when the symbol is unknown to the parser.\n getSymbolName: function parser_getSymbolName(symbol) {\n if (this.terminals_[symbol]) {\n return this.terminals_[symbol];\n }\n\n // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up.\n //\n // An example of this may be where a rule\'s action code contains a call like this:\n //\n // parser.getSymbolName(#$)\n //\n // to obtain a human-readable name of the current grammar rule.\n var s = this.symbols_;\n for (var key in s) {\n if (s[key] === symbol) {\n return key;\n }\n }\n return null;\n },\n\n // Return a more-or-less human-readable description of the given symbol, when available,\n // or the symbol itself, serving as its own \'description\' for lack of something better to serve up.\n //\n // Return NULL when the symbol is unknown to the parser.\n describeSymbol: function parser_describeSymbol(symbol) {\n if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) {\n return this.terminal_descriptions_[symbol];\n }\n else if (symbol === this.EOF) {\n return \'end of input\';\n }\n var id = this.getSymbolName(symbol);\n if (id) {\n return this.quoteName(id);\n }\n return null;\n },\n\n // Produce a (more or less) human-readable list of expected tokens at the point of failure.\n //\n // The produced list may contain token or token set descriptions instead of the tokens\n // themselves to help turning this output into something that easier to read by humans\n // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*,\n // expected terminals and nonterminals is produced.\n //\n // The returned list (array) will not contain any duplicate entries.\n collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) {\n var TERROR = this.TERROR;\n var tokenset = [];\n var check = {};\n // Has this (error?) state been outfitted with a custom expectations description text for human consumption?\n // If so, use that one instead of the less palatable token set.\n if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) {\n return [\n this.state_descriptions_[state]\n ];\n }\n for (var p in this.table[state]) {\n p = +p;\n if (p !== TERROR) {\n var d = do_not_describe ? p : this.describeSymbol(p);\n if (d && !check[d]) {\n tokenset.push(d);\n check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries.\n }\n }\n }\n return tokenset;\n }\n'; +// --- END of define_parser_APIs_1 chunk --- -var api_set = define_parser_APIs_1(); +var api_set = new Function('', 'return { ' + define_parser_APIs_1 + ' };')(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- -parser.parse = 'function parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2).replace(re1, \' $1: \').replace(/[\\n\\s]+/g, \' \');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n var r = this.parseError(str, hash, this.JisonParserError);\n return r;\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n else {\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}'; +parser.parse = '\nfunction parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2)\n .replace(re1, \' $1: \')\n .replace(/[\\n\\s]+/g, \' \')\n // shorten yylloc object dumps too:\n .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, \'{L/C: ($1,$2)..($3,$4)\');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n return this.parseError(str, hash, this.JisonParserError);\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}\n'; // --- END parser kernel --- @@ -24702,7 +24644,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function go_(productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -24817,7 +24759,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -24833,7 +24775,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -24844,7 +24786,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -24872,7 +24814,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { diff --git a/dist/jison-cjs.js b/dist/jison-cjs.js index 9715c161b..a435c7355 100644 --- a/dist/jison-cjs.js +++ b/dist/jison-cjs.js @@ -1,24 +1,20 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); -var recast = require('@gerhobbelt/recast'); -var assert = require('assert'); -var XRegExp = require('@gerhobbelt/xregexp'); -var json5 = require('@gerhobbelt/json5'); -var astUtils = require('@gerhobbelt/ast-util'); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var fs = _interopDefault(require('fs')); +var path = _interopDefault(require('path')); +var recast = _interopDefault(require('@gerhobbelt/recast')); +var assert$1 = _interopDefault(require('assert')); +var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); +var json5 = _interopDefault(require('@gerhobbelt/json5')); +var astUtils = _interopDefault(require('@gerhobbelt/ast-util')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { return src.substr(0, searchString.length) === searchString; } -function chkBugger(src) { - src = '' + src; - if (src.match(/\bcov_\w+/)) { - console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); - } -} // tagged template string helper which removes the indentation common to all @@ -168,6 +164,16 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -274,7 +280,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } - chkBugger(sourcecode); + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -319,13 +325,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -404,15 +410,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -685,9 +701,6 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - /* parser generated by jison 0.6.1-215 */ /* @@ -1231,7 +1244,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1281,7 +1295,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1439,104 +1453,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, + + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4503,14 +4520,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -7540,7 +7557,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9188,7 +9204,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -9202,7 +9218,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -9211,7 +9227,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9400,7 +9416,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9669,9 +9685,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9824,8 +9840,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9840,7 +9856,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9963,6 +9979,14 @@ var version$1 = '0.6.1-215'; // require('./package. +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -10154,7 +10178,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -10162,7 +10186,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -10243,7 +10267,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); - chkBugger(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10390,7 +10414,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10447,7 +10471,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10502,7 +10526,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10548,7 +10572,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10639,7 +10663,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10676,7 +10700,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10744,7 +10768,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10791,7 +10815,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -11004,7 +11028,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -11033,10 +11057,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); - chkBugger(sourcecode); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -11103,11 +11128,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -11118,7 +11143,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -11128,7 +11153,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -11141,8 +11166,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -11153,8 +11178,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12464,7 +12489,7 @@ return `{ // --- END lexer kernel --- } -chkBugger(getRegExpLexerPrototype()); +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$2` return ${getRegExpLexerPrototype()}; `))(); @@ -12808,9 +12833,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12854,8 +12879,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -13770,7 +13795,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -13820,7 +13846,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13862,104 +13888,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, + + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 11, @@ -17101,9 +17130,6 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - /* parser generated by jison 0.6.1-215 */ /* @@ -17647,7 +17673,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -17697,7 +17724,7 @@ var parser$2 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -17849,104 +17876,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, + + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ s$1, @@ -20992,14 +21022,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -24029,7 +24059,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -26054,6 +26083,14 @@ var version = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -26075,6 +26112,7 @@ const defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -26102,7 +26140,7 @@ const defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -26472,8 +26510,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -26755,7 +26793,7 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -27051,21 +27089,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -27073,7 +27111,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -27086,12 +27124,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -27420,7 +27458,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens @@ -27443,7 +27481,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -27523,12 +27561,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -27557,8 +27595,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -27566,7 +27604,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } @@ -27799,8 +27837,8 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); var h = [ self.actionsAreAllDefault, self.actionsUseLocationAssignment, @@ -27832,7 +27870,8 @@ function mkParserFeatureHash(self) { self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, - self.options.defaultActionMode.join(','), + self.options.defaultActionMode, + self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, @@ -27843,11 +27882,15 @@ function mkParserFeatureHash(self) { self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, + self.options.moduleName, + self.options.parseParams, + self.options.ranges, + self.options.prettyCfg, '======================================', self.performAction, '======================================', ]; - return h.join(','); + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -27877,8 +27920,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include) @@ -27887,7 +27930,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -27953,8 +27996,7 @@ generator.buildProductionActions = function buildProductionActions() { function __b0rk_on_internal_failure(str) { var hash = yyparser.constructParseErrorInfo(str, null, null, false); - var r = yyparser.parseError(str, hash, yyparser.JisonParserError); - return r; + return yyparser.parseError(str, hash, yyparser.JisonParserError); } return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);` @@ -28079,8 +28121,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -28219,6 +28261,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch, }); } @@ -28230,12 +28273,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -28363,8 +28406,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -28550,7 +28593,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -28948,20 +28991,27 @@ generator.reportGrammarInformation = function reportGrammarInformation() { }; +// --- START of debugTraceSrc chunk --- +const debugTraceSrc = ` +function debug_trace() { + if (typeof Jison !== 'undefined' && Jison.print) { + Jison.print.apply(null, arguments); + } else if (typeof print !== 'undefined') { + print.apply(null, arguments); + } else if (typeof console !== 'undefined' && console.log) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(''); // prevent \`%.\` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args + console.log.apply(null, args); + } +} +`; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: (new Function('', debugTraceSrc + ` + return debug_trace;`))(), beforeprocessGrammar: function () { this.trace('Processing grammar.'); }, @@ -29005,7 +29055,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -29055,7 +29105,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -29458,7 +29508,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -29602,7 +29652,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -30209,8 +30259,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS` @@ -30263,8 +30313,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS` @@ -30928,7 +30978,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -30936,7 +30986,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -31148,7 +31198,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -31162,7 +31212,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = (bprod.newg_states || []); @@ -31296,6 +31346,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -31395,7 +31446,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // // Options: // - // default action mode: ............. ${this.options.defaultActionMode.join(',')} + // default action mode: ............. ${JSON.stringify(this.options.defaultActionMode)} + // test-compile action mode: ........ ${JSON.stringify(this.options.testCompileActionCode)} // try..catch: ...................... ${!this.options.noTryCatch} // default resolve on conflict: ..... ${!this.options.noDefaultResolve} // on-demand look-ahead: ............ ${this.onDemandLookahead} @@ -31493,7 +31545,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -31509,8 +31561,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - -var prelude = `// See also: + const prelude = ` +// See also: // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508 // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility // with userland code which might access the derived class in a 'classic' way. @@ -31559,8 +31611,8 @@ if (typeof Object.setPrototypeOf === 'function') { JisonParserError.prototype = Object.create(Error.prototype); } JisonParserError.prototype.constructor = JisonParserError; -JisonParserError.prototype.name = 'JisonParserError';`; - +JisonParserError.prototype.name = 'JisonParserError'; +`; // --- END parser error class --- return { @@ -31830,10 +31882,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -31863,7 +31915,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -31904,8 +31956,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -31918,7 +31970,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -32087,7 +32139,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var productionsDef = analyzeTableForCompression(productions); - var bp_code_container = ` + const bp_code_container = ` // helper: reconstruct the productions[] table function bp(s) { var rv = []; @@ -32103,7 +32155,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bda_code_container = ` + const bda_code_container = ` // helper: reconstruct the defaultActions[] table function bda(s) { var rv = {}; @@ -32117,7 +32169,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bt_code_container = ` + const bt_code_container = ` // helper: reconstruct the 'goto' table function bt(s) { var rv = []; @@ -32157,7 +32209,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var c_s_u_code_container = ` + const c_s_u_code_container = ` // helper: runlength encoding with increment step: code, length: step (default step = 0) // \`this\` references an array function s(c, l, a) { @@ -32236,8 +32288,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -const commonjsMain = ` +const commonJsMain = ` function (args) { // When the parser comes with its own \`main\` function, then use that one: if (typeof exports.parser.main === 'function') { @@ -32262,9 +32316,11 @@ function (args) { rv = dst; } return dst; -}`; +} +`; +// --- END of commonJsMain chunk --- -const commonjsMainImports = ` +const commonJsMainImports = ` var fs = require('fs'); var path = require('path'); `; @@ -32341,37 +32397,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert(typeof p === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(typeof p.yy === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1(typeof p === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(typeof p.yy === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(typeof p.symbols_ === 'object'); - assert(typeof p.terminals_ === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(typeof p.symbols_ === 'object'); + assert$1(typeof p.terminals_ === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(typeof p.table === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(typeof p.table === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(typeof p.constructParseErrorInfo === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(typeof p.options === 'object'); - assert(typeof p.cleanupAfterParse === 'object'); - assert(typeof p.yyMergeLocationInfo === 'object'); - assert(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); + assert$1(typeof p.constructParseErrorInfo === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(typeof p.options === 'object'); + assert$1(typeof p.cleanupAfterParse === 'object'); + assert$1(typeof p.yyMergeLocationInfo === 'object'); + assert$1(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -32408,6 +32464,7 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; +// --- START parser Error class chunk --- const parseErrorSourceCode = ` function parseError(str, hash, ExceptionClass) { if (hash.recoverable) { @@ -32424,7 +32481,9 @@ function parseError(str, hash, ExceptionClass) { } throw new ExceptionClass(str, hash); } -}`; // END of parseErrorSourceCode chunk +} +`; +// --- END of parseErrorSourceCode chunk --- chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); @@ -32438,9 +32497,11 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -var define_parser_APIs_1 = ` +const define_parser_APIs_1 = ` TERROR: 2, EOF: 1, @@ -32544,6 +32605,7 @@ var define_parser_APIs_1 = ` return tokenset; } `; +// --- END of define_parser_APIs_1 chunk --- var api_set = (new Function('', 'return { ' + define_parser_APIs_1 + ' };'))(); for (var api in api_set) { @@ -32552,7 +32614,8 @@ for (var api in api_set) { // --- START parser kernel --- -parser.parse = `function parse(input, parseParams) { +parser.parse = ` +function parse(input, parseParams) { var self = this; var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage) var sstack = new Array(128); // state stack: stores states (column storage) @@ -34041,7 +34104,8 @@ parser.parse = `function parse(input, parseParams) { } // /finally return retval; -}`; +} +`; // --- END parser kernel --- @@ -34090,7 +34154,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function (productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -34210,7 +34274,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -34226,7 +34290,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -34237,7 +34301,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -34265,7 +34329,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { diff --git a/dist/jison-es6.js b/dist/jison-es6.js index 519af96b0..4aef33a9d 100644 --- a/dist/jison-es6.js +++ b/dist/jison-es6.js @@ -1,7 +1,7 @@ import fs from 'fs'; import path from 'path'; import recast from '@gerhobbelt/recast'; -import assert from 'assert'; +import assert$1 from 'assert'; import XRegExp from '@gerhobbelt/xregexp'; import json5 from '@gerhobbelt/json5'; import astUtils from '@gerhobbelt/ast-util'; @@ -11,12 +11,6 @@ function startsWith(src, searchString) { return src.substr(0, searchString.length) === searchString; } -function chkBugger(src) { - src = '' + src; - if (src.match(/\bcov_\w+/)) { - console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); - } -} // tagged template string helper which removes the indentation common to all @@ -166,6 +160,16 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -272,7 +276,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } - chkBugger(sourcecode); + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -317,13 +321,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -402,15 +406,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -683,9 +697,6 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - /* parser generated by jison 0.6.1-215 */ /* @@ -1229,7 +1240,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1279,7 +1291,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1437,104 +1449,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, + + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4501,14 +4516,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -7538,7 +7553,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9186,7 +9200,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -9200,7 +9214,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -9209,7 +9223,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9398,7 +9412,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9667,9 +9681,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9822,8 +9836,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9838,7 +9852,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9961,6 +9975,14 @@ var version$1 = '0.6.1-215'; // require('./package. +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -10152,7 +10174,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -10160,7 +10182,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -10241,7 +10263,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); - chkBugger(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10388,7 +10410,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10445,7 +10467,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10500,7 +10522,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10546,7 +10568,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10637,7 +10659,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10674,7 +10696,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10742,7 +10764,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10789,7 +10811,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -11002,7 +11024,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -11031,10 +11053,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); - chkBugger(sourcecode); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -11101,11 +11124,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -11116,7 +11139,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -11126,7 +11149,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -11139,8 +11162,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -11151,8 +11174,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12462,7 +12485,7 @@ return `{ // --- END lexer kernel --- } -chkBugger(getRegExpLexerPrototype()); +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$2` return ${getRegExpLexerPrototype()}; `))(); @@ -12806,9 +12829,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12852,8 +12875,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -13768,7 +13791,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -13818,7 +13842,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13860,104 +13884,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, + + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 11, @@ -17099,9 +17126,6 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - /* parser generated by jison 0.6.1-215 */ /* @@ -17645,7 +17669,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -17695,7 +17720,7 @@ var parser$2 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -17847,104 +17872,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, + + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ s$1, @@ -20990,14 +21018,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -24027,7 +24055,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -26052,6 +26079,14 @@ var version = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -26073,6 +26108,7 @@ const defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -26100,7 +26136,7 @@ const defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -26470,8 +26506,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -26753,7 +26789,7 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -27049,21 +27085,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -27071,7 +27107,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -27084,12 +27120,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -27418,7 +27454,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens @@ -27441,7 +27477,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -27521,12 +27557,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -27555,8 +27591,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -27564,7 +27600,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } @@ -27797,8 +27833,8 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); var h = [ self.actionsAreAllDefault, self.actionsUseLocationAssignment, @@ -27830,7 +27866,8 @@ function mkParserFeatureHash(self) { self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, - self.options.defaultActionMode.join(','), + self.options.defaultActionMode, + self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, @@ -27841,11 +27878,15 @@ function mkParserFeatureHash(self) { self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, + self.options.moduleName, + self.options.parseParams, + self.options.ranges, + self.options.prettyCfg, '======================================', self.performAction, '======================================', ]; - return h.join(','); + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -27875,8 +27916,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include) @@ -27885,7 +27926,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -27951,8 +27992,7 @@ generator.buildProductionActions = function buildProductionActions() { function __b0rk_on_internal_failure(str) { var hash = yyparser.constructParseErrorInfo(str, null, null, false); - var r = yyparser.parseError(str, hash, yyparser.JisonParserError); - return r; + return yyparser.parseError(str, hash, yyparser.JisonParserError); } return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);` @@ -28077,8 +28117,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -28217,6 +28257,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch, }); } @@ -28228,12 +28269,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -28361,8 +28402,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -28548,7 +28589,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -28946,20 +28987,27 @@ generator.reportGrammarInformation = function reportGrammarInformation() { }; +// --- START of debugTraceSrc chunk --- +const debugTraceSrc = ` +function debug_trace() { + if (typeof Jison !== 'undefined' && Jison.print) { + Jison.print.apply(null, arguments); + } else if (typeof print !== 'undefined') { + print.apply(null, arguments); + } else if (typeof console !== 'undefined' && console.log) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(''); // prevent \`%.\` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args + console.log.apply(null, args); + } +} +`; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: (new Function('', debugTraceSrc + ` + return debug_trace;`))(), beforeprocessGrammar: function () { this.trace('Processing grammar.'); }, @@ -29003,7 +29051,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -29053,7 +29101,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -29456,7 +29504,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -29600,7 +29648,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -30207,8 +30255,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS` @@ -30261,8 +30309,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS` @@ -30926,7 +30974,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -30934,7 +30982,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -31146,7 +31194,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -31160,7 +31208,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = (bprod.newg_states || []); @@ -31294,6 +31342,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -31393,7 +31442,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // // Options: // - // default action mode: ............. ${this.options.defaultActionMode.join(',')} + // default action mode: ............. ${JSON.stringify(this.options.defaultActionMode)} + // test-compile action mode: ........ ${JSON.stringify(this.options.testCompileActionCode)} // try..catch: ...................... ${!this.options.noTryCatch} // default resolve on conflict: ..... ${!this.options.noDefaultResolve} // on-demand look-ahead: ............ ${this.onDemandLookahead} @@ -31491,7 +31541,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -31507,8 +31557,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - -var prelude = `// See also: + const prelude = ` +// See also: // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508 // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility // with userland code which might access the derived class in a 'classic' way. @@ -31557,8 +31607,8 @@ if (typeof Object.setPrototypeOf === 'function') { JisonParserError.prototype = Object.create(Error.prototype); } JisonParserError.prototype.constructor = JisonParserError; -JisonParserError.prototype.name = 'JisonParserError';`; - +JisonParserError.prototype.name = 'JisonParserError'; +`; // --- END parser error class --- return { @@ -31828,10 +31878,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -31861,7 +31911,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -31902,8 +31952,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -31916,7 +31966,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -32085,7 +32135,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var productionsDef = analyzeTableForCompression(productions); - var bp_code_container = ` + const bp_code_container = ` // helper: reconstruct the productions[] table function bp(s) { var rv = []; @@ -32101,7 +32151,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bda_code_container = ` + const bda_code_container = ` // helper: reconstruct the defaultActions[] table function bda(s) { var rv = {}; @@ -32115,7 +32165,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bt_code_container = ` + const bt_code_container = ` // helper: reconstruct the 'goto' table function bt(s) { var rv = []; @@ -32155,7 +32205,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var c_s_u_code_container = ` + const c_s_u_code_container = ` // helper: runlength encoding with increment step: code, length: step (default step = 0) // \`this\` references an array function s(c, l, a) { @@ -32234,8 +32284,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -const commonjsMain = ` +const commonJsMain = ` function (args) { // When the parser comes with its own \`main\` function, then use that one: if (typeof exports.parser.main === 'function') { @@ -32260,9 +32312,11 @@ function (args) { rv = dst; } return dst; -}`; +} +`; +// --- END of commonJsMain chunk --- -const commonjsMainImports = ` +const commonJsMainImports = ` var fs = require('fs'); var path = require('path'); `; @@ -32339,37 +32393,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert(typeof p === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(typeof p.yy === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1(typeof p === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(typeof p.yy === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(typeof p.symbols_ === 'object'); - assert(typeof p.terminals_ === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(typeof p.symbols_ === 'object'); + assert$1(typeof p.terminals_ === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(typeof p.table === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(typeof p.table === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(typeof p.constructParseErrorInfo === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(typeof p.options === 'object'); - assert(typeof p.cleanupAfterParse === 'object'); - assert(typeof p.yyMergeLocationInfo === 'object'); - assert(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); + assert$1(typeof p.constructParseErrorInfo === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(typeof p.options === 'object'); + assert$1(typeof p.cleanupAfterParse === 'object'); + assert$1(typeof p.yyMergeLocationInfo === 'object'); + assert$1(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -32406,6 +32460,7 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; +// --- START parser Error class chunk --- const parseErrorSourceCode = ` function parseError(str, hash, ExceptionClass) { if (hash.recoverable) { @@ -32422,7 +32477,9 @@ function parseError(str, hash, ExceptionClass) { } throw new ExceptionClass(str, hash); } -}`; // END of parseErrorSourceCode chunk +} +`; +// --- END of parseErrorSourceCode chunk --- chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); @@ -32436,9 +32493,11 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -var define_parser_APIs_1 = ` +const define_parser_APIs_1 = ` TERROR: 2, EOF: 1, @@ -32542,6 +32601,7 @@ var define_parser_APIs_1 = ` return tokenset; } `; +// --- END of define_parser_APIs_1 chunk --- var api_set = (new Function('', 'return { ' + define_parser_APIs_1 + ' };'))(); for (var api in api_set) { @@ -32550,7 +32610,8 @@ for (var api in api_set) { // --- START parser kernel --- -parser.parse = `function parse(input, parseParams) { +parser.parse = ` +function parse(input, parseParams) { var self = this; var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage) var sstack = new Array(128); // state stack: stores states (column storage) @@ -34039,7 +34100,8 @@ parser.parse = `function parse(input, parseParams) { } // /finally return retval; -}`; +} +`; // --- END parser kernel --- @@ -34088,7 +34150,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function (productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -34208,7 +34270,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -34224,7 +34286,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -34235,7 +34297,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -34263,7 +34325,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { diff --git a/dist/jison-umd-es5.js b/dist/jison-umd-es5.js index 304f9b015..b7853beb6 100644 --- a/dist/jison-umd-es5.js +++ b/dist/jison-umd-es5.js @@ -107,14 +107,14 @@ var _templateObject = _taggedTemplateLiteral(['\n There\'s an error in yo function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } (function (global, factory) { - (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('@gerhobbelt/ast-util')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5', '@gerhobbelt/ast-util'], factory) : global.jison = factory(global.fs, global.path, global.recast, global.assert, global.XRegExp, global.json5, global.astUtils); -})(undefined, function (fs, path, recast, assert, XRegExp, json5, astUtils) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('@gerhobbelt/ast-util')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5', '@gerhobbelt/ast-util'], factory) : global.jison = factory(global.fs, global.path, global.recast, global.assert$1, global.XRegExp, global.json5, global.astUtils); +})(undefined, function (fs, path, recast, assert$1, XRegExp, json5, astUtils) { 'use strict'; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; - assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; + assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; astUtils = astUtils && astUtils.hasOwnProperty('default') ? astUtils['default'] : astUtils; @@ -269,6 +269,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -359,6 +366,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -398,13 +406,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi //import astUtils from '@gerhobbelt/ast-util'; - assert(recast); + assert$1(recast); var types = recast.types; - assert(types); + assert$1(types); var namedTypes = types.namedTypes; - assert(namedTypes); + assert$1(namedTypes); var b = types.builders; - assert(b); + assert$1(b); // //assert(astUtils); @@ -468,15 +476,24 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi checkActionBlock: checkActionBlock }; + function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -748,10 +765,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var Set = typal.construct(setMixin); - // hack: - var assert$1; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1277,7 +1291,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2866,14 +2881,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2962,8 +2977,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3518,14 +3532,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -4021,13 +4036,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -4040,7 +4055,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5639,7 +5654,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6955,7 +6969,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6969,7 +6983,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6978,7 +6992,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -7162,7 +7176,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7428,9 +7442,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7580,8 +7594,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7596,7 +7610,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7710,6 +7724,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var version$1 = '0.6.1-215'; // require('./package.json').version; + function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7895,7 +7916,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7903,7 +7924,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7984,6 +8005,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -8124,7 +8146,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -8181,7 +8203,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -8236,7 +8258,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -8281,7 +8303,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8372,7 +8394,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8409,7 +8431,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8474,7 +8496,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8521,7 +8543,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8654,7 +8676,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8678,6 +8700,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8744,11 +8767,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8759,14 +8782,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8779,8 +8802,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8791,8 +8814,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8885,6 +8908,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // --- END lexer kernel --- } + chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS$2(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8948,6 +8972,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -9106,6 +9131,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -9172,9 +9198,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -9209,8 +9235,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -9311,7 +9337,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi RegExpLexer.mkIdentifier = mkIdentifier$3; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -9825,7 +9851,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -10587,13 +10614,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -10605,7 +10632,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -12696,10 +12723,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return rv; } - // hack: - var assert$2; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13225,7 +13249,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -14857,14 +14882,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -14953,8 +14978,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -15509,14 +15533,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -16012,13 +16037,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -16031,7 +16056,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17630,7 +17655,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -19268,6 +19292,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var devDebug = 0; + function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -19289,6 +19320,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -19316,7 +19348,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -19687,8 +19719,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -19949,13 +19981,26 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -20247,21 +20292,21 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -20269,7 +20314,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -20282,12 +20327,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -20608,7 +20653,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens // as used in a rule like this: `rule: A ' ' B;` which should produce 3 tokens for the @@ -20630,7 +20675,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -20710,12 +20755,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -20744,8 +20789,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -20753,7 +20798,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } else { @@ -20941,10 +20986,10 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); - var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode.join(','), self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, '======================================', self.performAction, '======================================']; - return h.join(','); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); + var h = [self.actionsAreAllDefault, self.actionsUseLocationAssignment, self.actionsUseLocationTracking, self.actionsUseParseError, self.actionsUseValueAssignment, self.actionsUseValueTracking, self.actionsUseYYCLEARIN, self.actionsUseYYERROK, self.actionsUseYYERROR, self.actionsUseYYLENG, self.actionsUseYYLINENO, self.actionsUseYYLOC, self.actionsUseYYRECOVERING, self.actionsUseYYRULELENGTH, self.actionsUseYYMERGELOCATIONINFO, self.actionsUseYYSSTACK, self.actionsUseYYSTACK, self.actionsUseYYSTACKPOINTER, self.actionsUseYYTEXT, self.hasErrorRecovery, self.hasErrorReporting, self.onDemandLookahead, self.options.compressTables, self.options.debug, self.options.errorRecoveryTokenDiscardCount, self.options.exportAllTables.enabled, self.options.exportSourceCode.enabled, self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, self.options.defaultActionMode, self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, self.options.moduleMainImports, self.options.noTryCatch, self.options.numExpectedConflictStates, self.options.outputDebugTables, self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, self.options.moduleName, self.options.parseParams, self.options.ranges, self.options.prettyCfg, '======================================', self.performAction, '======================================']; + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -20972,8 +21017,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include).replace(/#([^#\s\r\n]+)#/g, function (_, sym) { @@ -20981,7 +21026,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -21022,7 +21067,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (missingActions.length) { console.warn("WARNING: missing actions for states: ", missingActions); - actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n var r = yyparser.parseError(str, hash, yyparser.JisonParserError);\n return r;\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); + actions.push('default:\n // default action for all unlisted resolve states: ' + missingActions.join(', ') + '\n\n // When we hit this entry, it\'s always a non-recoverable issue as this is a severe internal parser state failure:\n function __b0rk_on_internal_failure(str) {\n var hash = yyparser.constructParseErrorInfo(str, null, null, false);\n\n return yyparser.parseError(str, hash, yyparser.JisonParserError);\n }\n\n return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);'); } actions.push('}'); @@ -21133,8 +21178,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -21275,6 +21320,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch }); } @@ -21286,12 +21332,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -21406,8 +21452,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -21587,7 +21633,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -21879,7 +21925,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; // no-op. implemented in debug mixin - generator.trace = function no_op_trace() {}; + generator.trace = new Function('', 'function no_op_trace() { }\nreturn no_op_trace;')(); + //generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -21973,20 +22020,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi this.warn('\n'); }; + // --- START of debugTraceSrc chunk --- + var debugTraceSrc = '\nfunction debug_trace() {\n if (typeof Jison !== \'undefined\' && Jison.print) {\n Jison.print.apply(null, arguments);\n } else if (typeof print !== \'undefined\') {\n print.apply(null, arguments);\n } else if (typeof console !== \'undefined\' && console.log) {\n var args = Array.prototype.slice.call(arguments, 0);\n args.unshift(\'\'); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args\n console.log.apply(null, args);\n }\n}\n'; + // --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: new Function('', debugTraceSrc + '\n return debug_trace;')(), beforeprocessGrammar: function beforeprocessGrammar() { this.trace('Processing grammar.'); }, @@ -22028,7 +22069,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -22078,7 +22119,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -22485,7 +22526,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -22629,7 +22670,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -22841,8 +22882,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS(_templateObject96, moduleImportsAsCode, moduleNameAsCode.trim())); exportMain = 'main: yyExecMain,'; @@ -22861,8 +22902,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS(_templateObject99, moduleImportsAsCode, moduleNameAsCode.trim()); } @@ -23412,7 +23453,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -23420,7 +23461,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -23624,7 +23665,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -23638,7 +23679,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = bprod.newg_states || []; @@ -23772,6 +23813,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -23864,12 +23906,12 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // produce a hash lookup table from the terminal set exportDest.terminalTable = produceTerminalTable(this.terminals_); - var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + this.options.defaultActionMode.join(',') + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; - moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([String(define_parser_APIs_1).replace(/^[\s\S]+?return \{/, '').replace(/\};[s\r\n]+\}\s*$/, '').replace(/^ /mg, '').trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); + var moduleCode = '{\n // Code Generator Information Report\n // ---------------------------------\n //\n // Options:\n //\n // default action mode: ............. ' + JSON.stringify(this.options.defaultActionMode) + '\n // test-compile action mode: ........ ' + JSON.stringify(this.options.testCompileActionCode) + '\n // try..catch: ...................... ' + !this.options.noTryCatch + '\n // default resolve on conflict: ..... ' + !this.options.noDefaultResolve + '\n // on-demand look-ahead: ............ ' + this.onDemandLookahead + '\n // error recovery token skip maximum: ' + this.options.errorRecoveryTokenDiscardCount + '\n // yyerror in parse actions is: ..... ' + (this.options.parserErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // yyerror in lexer actions and other non-fatal lexer are:\n // .................................. ' + (this.options.lexerErrorsAreRecoverable ? 'recoverable' : 'NOT recoverable') + ',\n // debug grammar/output: ............ ' + this.options.debug + '\n // has partial LR conflict upgrade: ' + this.options.hasPartialLrUpgradeOnConflict + '\n // rudimentary token-stack support: ' + this.options.tokenStack + '\n // parser table compression mode: ... ' + this.options.compressTables + '\n // export debug tables: ............. ' + this.options.outputDebugTables + '\n // export *all* tables: ............. ' + this.options.exportAllTables.enabled + '\n // module type: ..................... ' + this.options.moduleType + '\n // parser engine type: .............. ' + this.options.type + '\n // output main() in the module: ..... ' + this.options.noMain + '\n // has user-specified main(): ....... ' + !!this.options.moduleMain + '\n // has user-specified require()/import modules for main():\n // .................................. ' + !!this.options.moduleMainImports + '\n // number of expected conflicts: .... ' + this.options.numExpectedConflictStates + '\n //\n //\n // Parser Analysis flags:\n //\n // no significant actions (parser is a language matcher only):\n // .................................. ' + this.actionsAreAllDefault + '\n // uses yyleng: ..................... ' + this.actionsUseYYLENG + '\n // uses yylineno: ................... ' + this.actionsUseYYLINENO + '\n // uses yytext: ..................... ' + this.actionsUseYYTEXT + '\n // uses yylloc: ..................... ' + this.actionsUseYYLOC + '\n // uses ParseError API: ............. ' + this.actionsUseParseError + '\n // uses YYERROR: .................... ' + this.actionsUseYYERROR + '\n // uses YYRECOVERING: ............... ' + this.actionsUseYYRECOVERING + '\n // uses YYERROK: .................... ' + this.actionsUseYYERROK + '\n // uses YYCLEARIN: .................. ' + this.actionsUseYYCLEARIN + '\n // tracks rule values: .............. ' + this.actionsUseValueTracking + '\n // assigns rule values: ............. ' + this.actionsUseValueAssignment + '\n // uses location tracking: .......... ' + this.actionsUseLocationTracking + '\n // assigns location: ................ ' + this.actionsUseLocationAssignment + '\n // uses yystack: .................... ' + this.actionsUseYYSTACK + '\n // uses yysstack: ................... ' + this.actionsUseYYSSTACK + '\n // uses yysp: ....................... ' + this.actionsUseYYSTACKPOINTER + '\n // uses yyrulelength: ............... ' + this.actionsUseYYRULELENGTH + '\n // uses yyMergeLocationInfo API: .... ' + this.actionsUseYYMERGELOCATIONINFO + '\n // has error recovery: .............. ' + this.hasErrorRecovery + '\n // has error reporting: ............. ' + this.hasErrorReporting + '\n //\n // --------- END OF REPORT -----------\n\n'; + moduleCode += ['trace: ' + String(this.trace || parser.trace), 'JisonParserError: JisonParserError', 'yy: {}', 'options: ' + produceOptions(this.options), 'symbols_: ' + JSON.stringify(symbolTable, null, 2), 'terminals_: ' + JSON.stringify(this.terminals_, null, 2).replace(/"([0-9]+)":/g, '$1:')].concat(rulesLst ? 'nonterminals_: ' + rulesLst : []).concat(descrLst ? 'terminal_descriptions_: ' + descrLst : []).concat([define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode]).concat(String(this.performAction).trim() !== '' ? 'performAction: ' + String(this.performAction) : []).concat(['table: ' + tableCode.tableCode, 'defaultActions: ' + tableCode.defaultActionsCode, 'parseError: ' + String(this.parseError || parseErrorSourceCode), 'parse: ' + parseFn]).concat(this.actionsUseYYERROR ? 'yyError: 1' : []).concat(this.actionsUseYYRECOVERING ? 'yyRecovering: 1' : []).concat(this.actionsUseYYERROK ? 'yyErrOk: 1' : []).concat(this.actionsUseYYCLEARIN ? 'yyClearIn: 1' : []).join(',\n'); moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -23882,9 +23924,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - - var prelude = '// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';'; - + var prelude = '\n// See also:\n// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508\n// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility\n// with userland code which might access the derived class in a \'classic\' way.\nfunction JisonParserError(msg, hash) {\n Object.defineProperty(this, \'name\', {\n enumerable: false,\n writable: false,\n value: \'JisonParserError\'\n });\n\n if (msg == null) msg = \'???\';\n\n Object.defineProperty(this, \'message\', {\n enumerable: false,\n writable: true,\n value: msg\n });\n\n this.hash = hash;\n\n var stacktrace;\n if (hash && hash.exception instanceof Error) {\n var ex2 = hash.exception;\n this.message = ex2.message || msg;\n stacktrace = ex2.stack;\n }\n if (!stacktrace) {\n if (Error.hasOwnProperty(\'captureStackTrace\')) { // V8/Chrome engine\n Error.captureStackTrace(this, this.constructor);\n } else {\n stacktrace = (new Error(msg)).stack;\n }\n }\n if (stacktrace) {\n Object.defineProperty(this, \'stack\', {\n enumerable: false,\n writable: false,\n value: stacktrace\n });\n }\n}\n\nif (typeof Object.setPrototypeOf === \'function\') {\n Object.setPrototypeOf(JisonParserError.prototype, Error.prototype);\n} else {\n JisonParserError.prototype = Object.create(Error.prototype);\n}\nJisonParserError.prototype.constructor = JisonParserError;\nJisonParserError.prototype.name = \'JisonParserError\';\n'; // --- END parser error class --- return { @@ -23913,6 +23953,10 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; }; + // Function that extends an object with the given value for all given keys + // e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } + var compressor1ObjectCode = '\nfunction x(k, v, o) {\n o = o || {};\n for (var l = k.length; l--; ) {\n o[k[l]] = v;\n }\n return o;\n}\n'; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -24005,7 +24049,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -24023,16 +24067,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; }; - // Function that extends an object with the given value for all given keys - // e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } - function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--;) { - o[k[l]] = v; - } - return o; - } - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -24150,10 +24184,10 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -24180,7 +24214,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -24219,8 +24253,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -24233,7 +24267,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot === 'undefined' ? 'undefined' : _typeof(slot)) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -24402,10 +24436,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; }; + // --- START of commonJsMain chunk --- + // // default main method for generated commonjs modules - var commonjsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}'; + var commonJsMain = '\nfunction (args) {\n // When the parser comes with its own `main` function, then use that one:\n if (typeof exports.parser.main === \'function\') {\n return exports.parser.main(args);\n }\n\n if (!args[1]) {\n console.log(\'Usage:\', path.basename(args[0]) + \' FILE\');\n process.exit(1);\n }\n var source = fs.readFileSync(path.normalize(args[1]), \'utf8\');\n var dst = exports.parser.parse(source);\n console.log(\'parser output:\\n\\n\', {\n type: typeof dst,\n value: dst\n });\n try {\n console.log("\\n\\nor as JSON:\\n", JSON.stringify(dst, null, 2));\n } catch (e) { /* ignore crashes; output MAY not be serializable! We are a generic bit of code, after all... */ }\n var rv = 0;\n if (typeof dst === \'number\' || typeof dst === \'boolean\') {\n rv = dst;\n }\n return dst;\n}\n'; + // --- END of commonJsMain chunk --- - var commonjsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; + var commonJsMainImports = '\nvar fs = require(\'fs\');\nvar path = require(\'path\');\n'; // debug mixin for LR parser generators @@ -24456,6 +24493,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var sourcecode = rmCommonWS(_templateObject101, sourceCodeDef.init, sourceCodeDef.src); var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -24463,37 +24501,37 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throwErrorOnCompileFailure: true }), "parser"); - assert((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(_typeof(p.yy) === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1((typeof p === 'undefined' ? 'undefined' : _typeof(p)) === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(_typeof(p.yy) === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(_typeof(p.symbols_) === 'object'); - assert(_typeof(p.terminals_) === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(_typeof(p.symbols_) === 'object'); + assert$1(_typeof(p.terminals_) === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(_typeof(p.table) === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(_typeof(p.table) === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(_typeof(p.constructParseErrorInfo) === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(_typeof(p.options) === 'object'); - assert(_typeof(p.cleanupAfterParse) === 'object'); - assert(_typeof(p.yyMergeLocationInfo) === 'object'); - assert(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); + assert$1(_typeof(p.constructParseErrorInfo) === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(_typeof(p.options) === 'object'); + assert$1(_typeof(p.cleanupAfterParse) === 'object'); + assert$1(_typeof(p.yyMergeLocationInfo) === 'object'); + assert$1(_typeof(p.lexer) === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -24530,8 +24568,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parser.warn = generator.warn; parser.error = generator.error; - var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}'; // END of parseErrorSourceCode chunk + // --- START parser Error class chunk --- + var parseErrorSourceCode = '\nfunction parseError(str, hash, ExceptionClass) {\n if (hash.recoverable) {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n hash.destroy(); // destroy... well, *almost*!\n } else {\n if (typeof this.trace === \'function\') {\n this.trace(str);\n }\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n throw new ExceptionClass(str, hash);\n }\n}\n'; + // --- END of parseErrorSourceCode chunk --- + chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -24542,119 +24583,20 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return lexer; }; - // wrapper function so we easily stringify the APIs defined inside to code *with comments* + // --- START parser API def chunk --- + // + // One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: - function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, - - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } - - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, - - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. - // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. - // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. - // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } - } - } - return tokenset; - } - }; - } + var define_parser_APIs_1 = '\n TERROR: 2,\n EOF: 1,\n\n // internals: defined here so the object *structure* doesn\'t get modified by parse() et al,\n // thus helping JIT compilers like Chrome V8.\n originalQuoteName: null,\n originalParseError: null,\n cleanupAfterParse: null,\n constructParseErrorInfo: null,\n yyMergeLocationInfo: null,\n\n __reentrant_call_depth: 0, // INTERNAL USE ONLY\n __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup\n\n // APIs which will be set up depending on user action code analysis:\n //yyRecovering: 0,\n //yyErrOk: 0,\n //yyClearIn: 0,\n\n // Helper APIs\n // -----------\n\n // Helper function which can be overridden by user code later on: put suitable quotes around\n // literal IDs in a description string.\n quoteName: function parser_quoteName(id_str) {\n return \'"\' + id_str + \'"\';\n },\n\n // Return the name of the given symbol (terminal or non-terminal) as a string, when available.\n //\n // Return NULL when the symbol is unknown to the parser.\n getSymbolName: function parser_getSymbolName(symbol) {\n if (this.terminals_[symbol]) {\n return this.terminals_[symbol];\n }\n\n // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up.\n //\n // An example of this may be where a rule\'s action code contains a call like this:\n //\n // parser.getSymbolName(#$)\n //\n // to obtain a human-readable name of the current grammar rule.\n var s = this.symbols_;\n for (var key in s) {\n if (s[key] === symbol) {\n return key;\n }\n }\n return null;\n },\n\n // Return a more-or-less human-readable description of the given symbol, when available,\n // or the symbol itself, serving as its own \'description\' for lack of something better to serve up.\n //\n // Return NULL when the symbol is unknown to the parser.\n describeSymbol: function parser_describeSymbol(symbol) {\n if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) {\n return this.terminal_descriptions_[symbol];\n }\n else if (symbol === this.EOF) {\n return \'end of input\';\n }\n var id = this.getSymbolName(symbol);\n if (id) {\n return this.quoteName(id);\n }\n return null;\n },\n\n // Produce a (more or less) human-readable list of expected tokens at the point of failure.\n //\n // The produced list may contain token or token set descriptions instead of the tokens\n // themselves to help turning this output into something that easier to read by humans\n // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*,\n // expected terminals and nonterminals is produced.\n //\n // The returned list (array) will not contain any duplicate entries.\n collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) {\n var TERROR = this.TERROR;\n var tokenset = [];\n var check = {};\n // Has this (error?) state been outfitted with a custom expectations description text for human consumption?\n // If so, use that one instead of the less palatable token set.\n if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) {\n return [\n this.state_descriptions_[state]\n ];\n }\n for (var p in this.table[state]) {\n p = +p;\n if (p !== TERROR) {\n var d = do_not_describe ? p : this.describeSymbol(p);\n if (d && !check[d]) {\n tokenset.push(d);\n check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries.\n }\n }\n }\n return tokenset;\n }\n'; + // --- END of define_parser_APIs_1 chunk --- - var api_set = define_parser_APIs_1(); + var api_set = new Function('', 'return { ' + define_parser_APIs_1 + ' };')(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- - parser.parse = 'function parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2).replace(re1, \' $1: \').replace(/[\\n\\s]+/g, \' \');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n var r = this.parseError(str, hash, this.JisonParserError);\n return r;\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n else {\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}'; + parser.parse = '\nfunction parse(input, parseParams) {\n var self = this;\n var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage)\n var sstack = new Array(128); // state stack: stores states (column storage)\n var tstack = []; // token stack (only used when `%options token_stack` support has been enabled)\n var vstack = new Array(128); // semantic value stack\n var lstack = new Array(128); // location stack\n var table = this.table;\n var sp = 0; // \'stack pointer\': index into the stacks\n var yyloc;\n var yytext;\n var yylineno;\n var yyleng;\n\n var symbol = 0;\n var preErrorSymbol = 0;\n var lastEofErrorStateDepth = Infinity;\n var recoveringErrorInfo = null;\n var recovering = 0; // (only used when the grammar contains error recovery rules)\n var TERROR = this.TERROR;\n var EOF = this.EOF;\n var ERROR_RECOVERY_TOKEN_DISCARD_COUNT = (this.options.errorRecoveryTokenDiscardCount | 0) || 3;\n var NO_ACTION = [0, YY_ERROR_RECOVERY_COMBINE_ID /* === table.length :: ensures that anyone using this new state will fail dramatically! */];\n\n var lexer;\n if (this.__lexer__) {\n lexer = this.__lexer__;\n } else {\n lexer = this.__lexer__ = Object.create(this.lexer);\n }\n\n var sharedState_yy = {\n parseError: undefined,\n quoteName: undefined,\n lexer: undefined,\n parser: undefined,\n pre_parse: undefined,\n post_parse: undefined,\n pre_lex: undefined,\n post_lex: undefined,\n parseParamsAsMembers: parseParamsAsMembers // WARNING: must be written this way for the code expanders to work correctly in both ES5 and ES6 modes!\n };\n\n var ASSERT;\n if (typeof assert !== \'function\') {\n ASSERT = function JisonAssert(cond, msg) {\n if (!cond) {\n throw new Error(\'assertion failed: \' + (msg || \'***\'));\n }\n };\n } else {\n ASSERT = assert;\n }\n\n this.yyGetSharedState = function yyGetSharedState() {\n return sharedState_yy;\n };\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n this.yyGetErrorInfoTrack = function yyGetErrorInfoTrack() {\n return recoveringErrorInfo;\n };\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // shallow clone objects, straight copy of simple `src` values\n // e.g. `lexer.yytext` MAY be a complex value object,\n // rather than a simple string/value.\n function shallow_copy(src) {\n if (typeof src === \'object\') {\n var dst = {};\n for (var k in src) {\n if (Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n }\n return src;\n }\n function shallow_copy_noclobber(dst, src) {\n for (var k in src) {\n if (typeof dst[k] === \'undefined\' && Object.prototype.hasOwnProperty.call(src, k)) {\n dst[k] = src[k];\n }\n }\n }\n function copy_yylloc(loc) {\n var rv = shallow_copy(loc);\n if (rv && rv.range) {\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n\n // copy state\n shallow_copy_noclobber(sharedState_yy, this.yy);\n\n sharedState_yy.lexer = lexer;\n sharedState_yy.parser = this;\n\n var yydebug = false;\n if (this.options.debug) {\n yydebug = function yydebug_impl(msg, obj) {\n var ref_list;\n var ref_names;\n\n function deepClone(from, sub) {\n if (sub == null) {\n ref_list = [];\n ref_names = [];\n sub = \'root\';\n }\n if (typeof from === \'function\') return \'[Function]\';\n if (from == null || typeof from !== \'object\') return from;\n if (from.constructor !== Object && from.constructor !== Array) {\n return from;\n }\n\n for (var i = 0, len = ref_list.length; i < len; i++) {\n if (ref_list[i] === from) {\n return \'[Circular/Xref:\' + ref_names[i] + \']\'; // circular or cross reference\n }\n }\n ref_list.push(from);\n ref_names.push(sub);\n\n var to = new from.constructor();\n for (var name in from) {\n if (name === \'parser\') continue;\n if (name === \'lexer\') continue;\n to[name] = deepClone(from[name], name);\n }\n return to;\n }\n\n obj = obj || {};\n if (obj.symbol) {\n obj.local_yytext = yytext;\n obj.lexer_yytext = lexer.yytext;\n obj.lexer_yylloc = lexer.yylloc;\n obj.lexer_yyllineno = lexer.yyllineno;\n }\n\n // warning: here we fetch from closure (stack et al)\n obj.symbol_stack = stack;\n obj.state_stack = sstack;\n obj.value_stack = vstack;\n obj.location_stack = lstack;\n obj.stack_pointer = sp;\n\n // ready the object for printing:\n obj = deepClone(obj);\n\n // wrap try/catch in a function to help the V8 JIT compiler...\n function yydebug_cvt(obj) {\n var js;\n try {\n var re1;\n if (typeof XRegExp === \'undefined\') {\n re1 = / \\"([a-z_][a-z_0-9. ]*)\\": /ig;\n } else {\n re1 = new XRegExp(\' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": \', \'g\');\n }\n js = JSON.stringify(obj, null, 2)\n .replace(re1, \' $1: \')\n .replace(/[\\n\\s]+/g, \' \')\n // shorten yylloc object dumps too:\n .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, \'{L/C: ($1,$2)..($3,$4)\');\n } catch (ex) {\n js = String(obj);\n }\n return js;\n }\n\n self.trace(msg, yydebug_cvt(obj), \'\\n\');\n };\n }\n\n // disable debugging at run-time ANYWAY when you\'ve *explicitly* set "yy.yydebug = false":\n if (sharedState_yy.yydebug === false) {\n yydebug = undefined;\n }\n\n // *Always* setup `yyError`, `YYRECOVERING`, `yyErrOk` and `yyClearIn` functions as it is paramount\n // to have *their* closure match ours -- if we only set them up once,\n // any subsequent `parse()` runs will fail in very obscure ways when\n // these functions are invoked in the user action code block(s) as\n // their closure will still refer to the `parse()` instance which set\n // them up. Hence we MUST set them up at the start of every `parse()` run!\n if (this.yyError) {\n this.yyError = function yyError(str /*, ...args */) {\n if (yydebug) yydebug(\'yyerror: \', { message: str, args: arguments, symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n var error_rule_depth = (this.options.parserErrorsAreRecoverable ? locateNearestErrorRecoveryRule(state) : -1);\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, (error_rule_depth >= 0));\n // append to the old one?\n if (recoveringErrorInfo) {\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n var v = this.shallowCopyErrorInfo(hash);\n v.yyError = true;\n v.errorRuleDepth = error_rule_depth;\n v.recovering = recovering;\n // v.stackSampleLength = error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH;\n\n recoveringErrorInfo.value_stack[esp] = v;\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n } else {\n recoveringErrorInfo = this.shallowCopyErrorInfo(hash);\n recoveringErrorInfo.yyError = true;\n recoveringErrorInfo.errorRuleDepth = error_rule_depth;\n recoveringErrorInfo.recovering = recovering;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n var expected = this.collect_expected_token_set(state);\n var hash = this.constructParseErrorInfo(str, null, expected, false);\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Add any extra args to the hash under the name `extra_error_attributes`:\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length) {\n hash.extra_error_attributes = args;\n }\n\n return this.parseError(str, hash, this.JisonParserError);\n };\n }\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n if (this.yyRecovering) {\n this.yyRecovering = function yyRecovering() {\n if (yydebug) yydebug(\'yyrecovering: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n return recovering;\n };\n }\n\n if (this.yyErrOk) {\n this.yyErrOk = function yyErrOk() {\n if (yydebug) yydebug(\'yyerrok: \', { symbol: symbol, state: state, newState: newState, recovering: recovering, action: action });\n recovering = 0;\n\n // DO NOT reset/cleanup `recoveringErrorInfo` yet: userland code\n // MAY invoke this API before the error is actually fully\n // recovered, in which case the parser recovery code won\'t be able\n // to append the skipped tokens to this info object.\n // \n // The rest of the kernel code is safe enough that it won\'t inadvertedly\n // re-use an old `recoveringErrorInfo` chunk so we\'ld better wait\n // with destruction/cleanup until the end of the parse or until another\n // fresh parse error rears its ugly head...\n //\n // if (recoveringErrorInfo && typeof recoveringErrorInfo.destroy === \'function\') {\n // recoveringErrorInfo.destroy();\n // recoveringErrorInfo = undefined;\n // }\n };\n }\n\n if (this.yyClearIn) {\n this.yyClearIn = function yyClearIn() {\n if (yydebug) yydebug(\'yyclearin: \', { symbol: symbol, newState: newState, recovering: recovering, action: action, preErrorSymbol: preErrorSymbol });\n if (symbol === TERROR) {\n symbol = 0;\n yytext = null;\n yyleng = 0;\n yyloc = undefined;\n }\n preErrorSymbol = 0;\n };\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n // Does the shared state override the default `parseError` that already comes with this instance?\n if (typeof sharedState_yy.parseError === \'function\') {\n this.parseError = function parseErrorAlt(str, hash, ExceptionClass) {\n if (!ExceptionClass) {\n ExceptionClass = this.JisonParserError;\n }\n return sharedState_yy.parseError.call(this, str, hash, ExceptionClass);\n };\n } else {\n this.parseError = this.originalParseError;\n }\n\n // Does the shared state override the default `quoteName` that already comes with this instance?\n if (typeof sharedState_yy.quoteName === \'function\') {\n this.quoteName = function quoteNameAlt(id_str) {\n return sharedState_yy.quoteName.call(this, id_str);\n };\n } else {\n this.quoteName = this.originalQuoteName;\n }\n\n // set up the cleanup function; make it an API so that external code can re-use this one in case of\n // calamities or when the `%options no-try-catch` option has been specified for the grammar, in which\n // case this parse() API method doesn\'t come with a `finally { ... }` block any more!\n //\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `sharedState`, etc. references will be *wrong*!\n this.cleanupAfterParse = function parser_cleanupAfterParse(resultValue, invoke_post_methods, do_not_nuke_errorinfos) {\n var rv;\n\n if (invoke_post_methods) {\n var hash;\n\n if (sharedState_yy.post_parse || this.post_parse) {\n // create an error hash info instance: we re-use this API in a **non-error situation**\n // as this one delivers all parser internals ready for access by userland code.\n hash = this.constructParseErrorInfo(null /* no error! */, null /* no exception! */, null, false);\n }\n\n if (sharedState_yy.post_parse) {\n rv = sharedState_yy.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n if (this.post_parse) {\n rv = this.post_parse.call(this, sharedState_yy, resultValue, hash);\n if (typeof rv !== \'undefined\') resultValue = rv;\n }\n\n // cleanup:\n if (hash && hash.destroy) {\n hash.destroy();\n }\n }\n\n if (this.__reentrant_call_depth > 1) return resultValue; // do not (yet) kill the sharedState when this is a reentrant run.\n\n // clean up the lingering lexer structures as well:\n if (lexer.cleanupAfterLex) {\n lexer.cleanupAfterLex(do_not_nuke_errorinfos);\n }\n\n // prevent lingering circular references from causing memory leaks:\n if (sharedState_yy) {\n sharedState_yy.lexer = undefined;\n sharedState_yy.parser = undefined;\n if (lexer.yy === sharedState_yy) {\n lexer.yy = undefined;\n }\n }\n sharedState_yy = undefined;\n this.parseError = this.originalParseError;\n this.quoteName = this.originalQuoteName;\n\n // nuke the vstack[] array at least as that one will still reference obsoleted user values.\n // To be safe, we nuke the other internal stack columns as well...\n stack.length = 0; // fastest way to nuke an array without overly bothering the GC\n sstack.length = 0;\n lstack.length = 0;\n vstack.length = 0;\n sp = 0;\n\n // nuke the error hash info instances created during this run.\n // Userland code must COPY any data/references\n // in the error hash instance(s) it is more permanently interested in.\n if (!do_not_nuke_errorinfos) {\n for (var i = this.__error_infos.length - 1; i >= 0; i--) {\n var el = this.__error_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_infos.length = 0;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n for (var i = this.__error_recovery_infos.length - 1; i >= 0; i--) {\n var el = this.__error_recovery_infos[i];\n if (el && typeof el.destroy === \'function\') {\n el.destroy();\n }\n }\n this.__error_recovery_infos.length = 0;\n\n // `recoveringErrorInfo` is also part of the `__error_recovery_infos` array,\n // hence has been destroyed already: no need to do that *twice*.\n if (recoveringErrorInfo) {\n recoveringErrorInfo = undefined;\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n return resultValue;\n };\n\n // merge yylloc info into a new yylloc instance.\n //\n // `first_index` and `last_index` MAY be UNDEFINED/NULL or these are indexes into the `lstack[]` location stack array.\n //\n // `first_yylloc` and `last_yylloc` MAY be UNDEFINED/NULL or explicit (custom or regular) `yylloc` instances, in which\n // case these override the corresponding first/last indexes.\n //\n // `dont_look_back` is an optional flag (default: FALSE), which instructs this merge operation NOT to search\n // through the parse location stack for a location, which would otherwise be used to construct the new (epsilon!)\n // yylloc info.\n //\n // Note: epsilon rule\'s yylloc situation is detected by passing both `first_index` and `first_yylloc` as UNDEFINED/NULL.\n this.yyMergeLocationInfo = function parser_yyMergeLocationInfo(first_index, last_index, first_yylloc, last_yylloc, dont_look_back) {\n var i1 = first_index | 0,\n i2 = last_index | 0;\n var l1 = first_yylloc,\n l2 = last_yylloc;\n var rv;\n\n // rules:\n // - first/last yylloc entries override first/last indexes\n\n if (!l1) {\n if (first_index != null) {\n for (var i = i1; i <= i2; i++) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n }\n\n if (!l2) {\n if (last_index != null) {\n for (var i = i2; i >= i1; i--) {\n l2 = lstack[i];\n if (l2) {\n break;\n }\n }\n }\n }\n\n // - detect if an epsilon rule is being processed and act accordingly:\n if (!l1 && first_index == null) {\n // epsilon rule span merger. With optional look-ahead in l2.\n if (!dont_look_back) {\n for (var i = (i1 || sp) - 1; i >= 0; i--) {\n l1 = lstack[i];\n if (l1) {\n break;\n }\n }\n }\n if (!l1) {\n if (!l2) {\n // when we still don\'t have any valid yylloc info, we\'re looking at an epsilon rule\n // without look-ahead and no preceding terms and/or `dont_look_back` set:\n // in that case we ca do nothing but return NULL/UNDEFINED:\n return undefined;\n } else {\n // shallow-copy L2: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l2);\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n return rv;\n }\n } else {\n // shallow-copy L1, then adjust first col/row 1 column past the end.\n rv = shallow_copy(l1);\n rv.first_line = rv.last_line;\n rv.first_column = rv.last_column;\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n rv.range[0] = rv.range[1];\n }\n\n if (l2) {\n // shallow-mixin L2, then adjust last col/row accordingly.\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n return rv;\n }\n }\n\n if (!l1) {\n l1 = l2;\n l2 = null;\n }\n if (!l1) {\n return undefined;\n }\n\n // shallow-copy L1|L2, before we try to adjust the yylloc values: after all, we MAY be looking\n // at unconventional yylloc info objects...\n rv = shallow_copy(l1);\n\n // first_line: ...,\n // first_column: ...,\n // last_line: ...,\n // last_column: ...,\n if (rv.range) {\n // shallow copy the yylloc ranges info to prevent us from modifying the original arguments\' entries:\n rv.range = rv.range.slice(0);\n }\n\n if (l2) {\n shallow_copy_noclobber(rv, l2);\n rv.last_line = l2.last_line;\n rv.last_column = l2.last_column;\n if (rv.range && l2.range) {\n rv.range[1] = l2.range[1];\n }\n }\n\n return rv;\n };\n\n // NOTE: as this API uses parse() as a closure, it MUST be set again on every parse() invocation,\n // or else your `lexer`, `sharedState`, etc. references will be *wrong*!\n this.constructParseErrorInfo = function parser_constructParseErrorInfo(msg, ex, expected, recoverable) {\n var pei = {\n errStr: msg,\n exception: ex,\n text: lexer.match,\n value: lexer.yytext,\n token: this.describeSymbol(symbol) || symbol,\n token_id: symbol,\n line: lexer.yylineno,\n loc: copy_yylloc(lexer.yylloc),\n expected: expected,\n recoverable: recoverable,\n state: state,\n action: action,\n new_state: newState,\n symbol_stack: stack,\n state_stack: sstack,\n value_stack: vstack,\n location_stack: lstack,\n stack_pointer: sp,\n yy: sharedState_yy,\n lexer: lexer,\n parser: this,\n\n // and make sure the error info doesn\'t stay due to potential\n // ref cycle via userland code manipulations.\n // These would otherwise all be memory leak opportunities!\n //\n // Note that only array and object references are nuked as those\n // constitute the set of elements which can produce a cyclic ref.\n // The rest of the members is kept intact as they are harmless.\n destroy: function destructParseErrorInfo() {\n // remove cyclic references added to error info:\n // info.yy = null;\n // info.lexer = null;\n // info.value = null;\n // info.value_stack = null;\n // ...\n var rec = !!this.recoverable;\n for (var key in this) {\n if (this.hasOwnProperty(key) && typeof key === \'object\') {\n this[key] = undefined;\n }\n }\n this.recoverable = rec;\n }\n };\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_infos.push(pei);\n return pei;\n };\n\n // clone some parts of the (possibly enhanced!) errorInfo object\n // to give them some persistence.\n this.shallowCopyErrorInfo = function parser_shallowCopyErrorInfo(p) {\n var rv = shallow_copy(p);\n\n // remove the large parts which can only cause cyclic references\n // and are otherwise available from the parser kernel anyway.\n delete rv.sharedState_yy;\n delete rv.parser;\n delete rv.lexer;\n\n // lexer.yytext MAY be a complex value object, rather than a simple string/value:\n rv.value = shallow_copy(rv.value);\n\n // yylloc info:\n rv.loc = copy_yylloc(rv.loc);\n\n // the \'expected\' set won\'t be modified, so no need to clone it:\n //rv.expected = rv.expected.slice(0);\n\n //symbol stack is a simple array:\n rv.symbol_stack = rv.symbol_stack.slice(0);\n // ditto for state stack:\n rv.state_stack = rv.state_stack.slice(0);\n // clone the yylloc\'s in the location stack?:\n rv.location_stack = rv.location_stack.map(copy_yylloc);\n // and the value stack may carry both simple and complex values:\n // shallow-copy the latter.\n rv.value_stack = rv.value_stack.map(shallow_copy);\n\n // and we don\'t bother with the sharedState_yy reference:\n //delete rv.yy;\n\n // now we prepare for tracking the COMBINE actions\n // in the error recovery code path:\n //\n // as we want to keep the maximum error info context, we\n // *scan* the state stack to find the first *empty* slot.\n // This position will surely be AT OR ABOVE the current\n // stack pointer, but we want to keep the \'used but discarded\'\n // part of the parse stacks *intact* as those slots carry\n // error context that may be useful when you want to produce\n // very detailed error diagnostic reports.\n //\n // ### Purpose of each stack pointer:\n //\n // - stack_pointer: points at the top of the parse stack\n // **as it existed at the time of the error\n // occurrence, i.e. at the time the stack\n // snapshot was taken and copied into the\n // errorInfo object.**\n // - base_pointer: the bottom of the **empty part** of the\n // stack, i.e. **the start of the rest of\n // the stack space /above/ the existing\n // parse stack. This section will be filled\n // by the error recovery process as it\n // travels the parse state machine to\n // arrive at the resolving error recovery rule.**\n // - info_stack_pointer:\n // this stack pointer points to the **top of\n // the error ecovery tracking stack space**, i.e.\n // this stack pointer takes up the role of\n // the `stack_pointer` for the error recovery\n // process. Any mutations in the **parse stack**\n // are **copy-appended** to this part of the\n // stack space, keeping the bottom part of the\n // stack (the \'snapshot\' part where the parse\n // state at the time of error occurrence was kept)\n // intact.\n // - root_failure_pointer:\n // copy of the `stack_pointer`...\n //\n for (var i = rv.stack_pointer; typeof rv.state_stack[i] !== \'undefined\'; i++) {\n // empty\n }\n rv.base_pointer = i;\n rv.info_stack_pointer = i;\n\n rv.root_failure_pointer = rv.stack_pointer;\n\n // track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!\n this.__error_recovery_infos.push(rv);\n\n return rv;\n };\n\n function getNonTerminalFromCode(symbol) {\n var tokenName = self.getSymbolName(symbol);\n if (!tokenName) {\n tokenName = symbol;\n }\n return tokenName;\n }\n\n//_lexer_without_token_stack:\n\n function stdLex() {\n var token = lexer.lex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n function fastLex() {\n var token = lexer.fastLex();\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n\n return token || EOF;\n }\n\n var lex = stdLex;\n\n//_lexer_with_token_stack:\n\n // lex function that supports token stacks\n function tokenStackLex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n // if token isn\'t its numeric value, convert\n if (typeof token !== \'number\') {\n token = self.symbols_[token] || token;\n }\n }\n\n return token || EOF;\n }\n\n//_lexer_with_token_stack_end:\n\n var state, action, r, t;\n var yyval = {\n $: true,\n _$: undefined,\n yy: sharedState_yy\n };\n var p;\n var yyrulelen;\n var this_production;\n var newState;\n var retval = false;\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // Return the rule stack depth where the nearest error rule can be found.\n // Return -1 when no error recovery rule was found.\n function locateNearestErrorRecoveryRule(state) {\n var stack_probe = sp - 1;\n var depth = 0;\n\n // try to recover from error\n while (stack_probe >= 0) {\n // check for error recovery rule in this state\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #test#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n var t = table[state][TERROR] || NO_ACTION;\n if (t[0]) {\n // We need to make sure we\'re not cycling forever:\n // once we hit EOF, even when we `yyerrok()` an error, we must\n // prevent the core from running forever,\n // e.g. when parent rules are still expecting certain input to\n // follow after this, for example when you handle an error inside a set\n // of braces which are matched by a parent rule in your grammar.\n //\n // Hence we require that every error handling/recovery attempt\n // *after we\'ve hit EOF* has a diminishing state stack: this means\n // we will ultimately have unwound the state stack entirely and thus\n // terminate the parse in a controlled fashion even when we have\n // very complex error/recovery code interplay in the core + user\n // action code blocks:\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #found#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n if (symbol === EOF) {\n if (lastEofErrorStateDepth > sp - 1 - depth) {\n lastEofErrorStateDepth = sp - 1 - depth;\n } else {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #skip#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n continue;\n }\n }\n return depth;\n }\n if (state === 0 /* $accept rule */ || stack_probe < 1) {\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #end=NIL#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n --stack_probe; // popStack(1): [symbol, action]\n state = sstack[stack_probe];\n ++depth;\n }\n if (yydebug) yydebug(\'locateNearestErrorRecoveryRule #EMPTY#: \', { symbol: symbol, state: state, depth: depth, stackidx: sp - 1 - depth, lastidx: lastEofErrorStateDepth });\n return -1; // No suitable error recovery rule available.\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n try {\n this.__reentrant_call_depth++;\n\n lexer.setInput(input, sharedState_yy);\n\n // NOTE: we *assume* no lexer pre/post handlers are set up *after* \n // this initial `setInput()` call: hence we can now check and decide\n // whether we\'ll go with the standard, slower, lex() API or the\n // `fast_lex()` one:\n if (typeof lexer.canIUse === \'function\') {\n var lexerInfo = lexer.canIUse();\n if (lexerInfo.fastLex && typeof fastLex === \'function\') {\n lex = fastLex;\n }\n } \n\n yyloc = lexer.yylloc;\n lstack[sp] = yyloc;\n vstack[sp] = null;\n sstack[sp] = 0;\n stack[sp] = 0;\n ++sp;\n\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyleng = lexer.yyleng;\n\n if (this.pre_parse) {\n this.pre_parse.call(this, sharedState_yy);\n }\n if (sharedState_yy.pre_parse) {\n sharedState_yy.pre_parse.call(this, sharedState_yy);\n }\n\n newState = sstack[sp - 1];\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n//_handle_error_with_recovery: // run this code when the grammar includes error recovery rules\n\n // handle parse error\n if (!action) {\n // first see if there\'s any chance at hitting an error recovery rule:\n var error_rule_depth = locateNearestErrorRecoveryRule(state);\n var errStr = null;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n if (!recovering) {\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, (error_rule_depth >= 0));\n\n // DO NOT cleanup the old one before we start the new error info track:\n // the old one will *linger* on the error stack and stay alive until we \n // invoke the parser\'s cleanup API!\n recoveringErrorInfo = this.shallowCopyErrorInfo(p);\n\n if (yydebug) yydebug(\'error recovery rule detected: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // Protect against overly blunt userland `parseError` code which *sets*\n // the `recoverable` flag without properly checking first:\n // we always terminate the parse when there\'s no recovery rule available anyhow!\n if (!p.recoverable || error_rule_depth < 0) {\n break;\n } else {\n // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process...\n }\n }\n\n if (yydebug) yydebug(\'after ERROR DETECT: \', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p });\n\n var esp = recoveringErrorInfo.info_stack_pointer;\n\n // just recovered from another error\n if (recovering === ERROR_RECOVERY_TOKEN_DISCARD_COUNT && error_rule_depth >= 0) {\n // SHIFT current lookahead and grab another\n recoveringErrorInfo.symbol_stack[esp] = symbol;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(lexer.yytext);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState; // push state\n ++esp;\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n preErrorSymbol = 0;\n symbol = lex();\n\n if (yydebug) yydebug(\'after ERROR RECOVERY-3: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol] });\n }\n\n // try to recover from error\n if (error_rule_depth < 0) {\n ASSERT(recovering > 0, "line 897");\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // barf a fatal hairball when we\'re out of look-ahead symbols and none hit a match\n // while we are still busy recovering from another error:\n var po = this.__error_infos[this.__error_infos.length - 1];\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parsing halted on line \' + (lexer.yylineno + 1) + \' while starting to recover from another error\';\n } else {\n errStr = \'Parsing halted while starting to recover from another error\';\n }\n\n if (po) {\n errStr += \' -- previous error which resulted in this fatal result: \' + po.errStr;\n } else {\n errStr += \': \';\n }\n\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n if (po) {\n p.extra_error_attributes = po;\n }\n\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n preErrorSymbol = (symbol === TERROR ? 0 : symbol); // save the lookahead token\n symbol = TERROR; // insert generic error symbol as new lookahead\n\n const EXTRA_STACK_SAMPLE_DEPTH = 3;\n\n // REDUCE/COMBINE the pushed terms/tokens to a new ERROR token:\n recoveringErrorInfo.symbol_stack[esp] = preErrorSymbol;\n if (errStr) {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n errStr: errStr,\n errorSymbolDescr: errSymbolDescr,\n expectedStr: expected,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n if (yydebug) yydebug(\'Error recovery process: pushed error info item on the info stack: \', {\n item: vstack[sp],\n sp,\n esp,\n vstack,\n stack,\n sstack,\n combineState: NO_ACTION[1]\n });\n } else {\n recoveringErrorInfo.value_stack[esp] = {\n yytext: shallow_copy(lexer.yytext),\n errorRuleDepth: error_rule_depth,\n stackSampleLength: error_rule_depth + EXTRA_STACK_SAMPLE_DEPTH\n };\n }\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lexer.yylloc);\n recoveringErrorInfo.state_stack[esp] = newState || NO_ACTION[1];\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n yyval.$ = recoveringErrorInfo;\n yyval._$ = undefined;\n\n yyrulelen = error_rule_depth;\n\n if (yydebug) yydebug(\'Error recovery process: performAction: COMBINE: \', {\n yyval, yytext, sp, pop_size: yyrulelen, vstack, stack, sstack,\n combineState: NO_ACTION[1]\n });\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, NO_ACTION[1], sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // and move the top entries + discarded part of the parse stacks onto the error info stack:\n for (var idx = sp - EXTRA_STACK_SAMPLE_DEPTH, top = idx + yyrulelen; idx < top; idx++, esp++) {\n recoveringErrorInfo.symbol_stack[esp] = stack[idx];\n recoveringErrorInfo.value_stack[esp] = shallow_copy(vstack[idx]);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(lstack[idx]);\n recoveringErrorInfo.state_stack[esp] = sstack[idx];\n }\n\n recoveringErrorInfo.symbol_stack[esp] = TERROR;\n recoveringErrorInfo.value_stack[esp] = shallow_copy(yyval.$);\n recoveringErrorInfo.location_stack[esp] = copy_yylloc(yyval._$);\n\n // goto new state = table[STATE][NONTERMINAL]\n newState = sstack[sp - 1];\n\n if (this.defaultActions[newState]) {\n recoveringErrorInfo.state_stack[esp] = this.defaultActions[newState];\n } else {\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n recoveringErrorInfo.state_stack[esp] = t[1];\n }\n\n ++esp;\n recoveringErrorInfo.info_stack_pointer = esp;\n\n // allow N (default: 3) real symbols to be shifted before reporting a new error\n recovering = ERROR_RECOVERY_TOKEN_DISCARD_COUNT;\n\n if (yydebug) yydebug(\'after ERROR POP: \', { error_rule_depth: error_rule_depth, symbol: symbol, preErrorSymbol: preErrorSymbol });\n\n // Now duplicate the standard parse machine here, at least its initial\n // couple of rounds until the TERROR symbol is **pushed onto the parse stack**,\n // as we wish to push something special then!\n //\n // Run the state machine in this copy of the parser state machine\n // until we *either* consume the error symbol (and its related information)\n // *or* we run into another error while recovering from this one\n // *or* we execute a `reduce` action which outputs a final parse\n // result (yes, that MAY happen!).\n //\n // We stay in this secondary parse loop until we have completed\n // the *error recovery phase* as the main parse loop (further below)\n // is optimized for regular parse operation and DOES NOT cope with\n // error recovery *at all*.\n //\n // We call the secondary parse loop just below the "slow parse loop",\n // while the main parse loop, which is an almost-duplicate of this one,\n // yet optimized for regular parse operation, is called the "fast\n // parse loop".\n //\n // Compare this to `bison` & (vanilla) `jison`, both of which have\n // only a single parse loop, which handles everything. Our goal is\n // to eke out every drop of performance in the main parse loop...\n\n ASSERT(recoveringErrorInfo, "line 1049");\n ASSERT(symbol === TERROR, "line 1050");\n ASSERT(!action, "line 1051");\n var errorSymbolFromParser = true;\n for (;;) {\n // retrieve state number from top of stack\n state = newState; // sstack[sp - 1];\n\n // use default actions if available\n if (this.defaultActions[state]) {\n action = 2;\n newState = this.defaultActions[state];\n } else {\n // The single `==` condition below covers both these `===` comparisons in a single\n // operation:\n //\n // if (symbol === null || typeof symbol === \'undefined\') ...\n if (!symbol) {\n symbol = lex();\n // **Warning: Edge Case**: the *lexer* may produce\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n }\n // read action for current state and first input\n t = (table[state] && table[state][symbol]) || NO_ACTION;\n newState = t[1];\n action = t[0];\n\n if (yydebug) yydebug(\'after FETCH/LEX: \', { symbol: symbol, symbolID: this.terminals_ && this.terminals_[symbol], state: state, newState: newState, recovering: recovering, action: action });\n\n // encountered another parse error? If so, break out to main loop\n // and take it from there!\n if (!action) {\n if (yydebug) yydebug(\'**NESTED ERROR DETECTED** while still recovering from previous error\');\n\n ASSERT(recoveringErrorInfo, "line 1087");\n\n // Prep state variables so that upon breaking out of\n // this "slow parse loop" and hitting the `continue;`\n // statement in the outer "fast parse loop" we redo\n // the exact same state table lookup as the one above\n // so that the outer=main loop will also correctly\n // detect the \'parse error\' state (`!action`) we have\n // just encountered above.\n newState = state;\n break;\n }\n }\n\n if (yydebug) yydebug(\'::: SLOW ERROR RECOVERY PHASE CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n //\n // SILENTLY SIGNAL that the outer "fast parse loop" should\n // take care of this internal error condition:\n // prevent useless code duplication now/here.\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n // ### Note/Warning ###\n //\n // The *lexer* may also produce TERROR tokens on its own,\n // so we specifically test for the TERROR we did set up\n // in the error recovery logic further above!\n if (symbol === TERROR && errorSymbolFromParser) {\n // Push a special value onto the stack when we\'re\n // shifting the `error` symbol that is related to the\n // error we\'re recovering from.\n ASSERT(recoveringErrorInfo, "line 1131");\n vstack[sp] = recoveringErrorInfo;\n lstack[sp] = this.yyMergeLocationInfo(null, null, recoveringErrorInfo.loc, lexer.yylloc, true);\n } else {\n ASSERT(symbol !== 0, "line 1135");\n ASSERT(preErrorSymbol === 0, "line 1136");\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n }\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n // **Warning: Edge Case**: the *lexer* may have produced\n // TERROR tokens of its own volition: *those* TERROR\n // tokens should be treated like *regular tokens*\n // i.e. tokens which have a lexer-provided `yyvalue`\n // and `yylloc`:\n errorSymbolFromParser = false;\n if (!preErrorSymbol) { // normal execution / no error\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n\n if (recovering > 0) {\n recovering--;\n if (yydebug) yydebug(\'... SHIFT:error rule matching: \', { recovering: recovering, symbol: symbol });\n }\n } else {\n // error just occurred, resume old lookahead f/ before error, *unless* that drops us straight back into error mode:\n ASSERT(recovering > 0, "line 1163");\n symbol = preErrorSymbol;\n preErrorSymbol = 0;\n if (yydebug) yydebug(\'... SHIFT:error recovery: \', { recovering: recovering, symbol: symbol });\n // read action for current state and first input\n t = (table[newState] && table[newState][symbol]) || NO_ACTION;\n if (!t[0] || symbol === TERROR) {\n // forget about that symbol and move forward: this wasn\'t a \'forgot to insert\' error type where\n // (simple) stuff might have been missing before the token which caused the error we\'re\n // recovering from now...\n //\n // Also check if the LookAhead symbol isn\'t the ERROR token we set as part of the error\n // recovery, for then this we would we idling (cycling) on the error forever.\n // Yes, this does not take into account the possibility that the *lexer* may have\n // produced a *new* TERROR token all by itself, but that would be a very peculiar grammar!\n if (yydebug) yydebug(\'... SHIFT:error recovery: re-application of old symbol doesn\\\'t work: instead, we\\\'re moving forward now. \', { recovering: recovering, symbol: symbol });\n symbol = 0;\n }\n }\n\n // once we have pushed the special ERROR token value,\n // we REMAIN in this inner, "slow parse loop" until\n // the entire error recovery phase has completed.\n //\n // ### Note About Edge Case ###\n //\n // Userland action code MAY already have \'reset\' the\n // error recovery phase marker `recovering` to ZERO(0)\n // while the error symbol hasn\'t been shifted onto\n // the stack yet. Hence we only exit this "slow parse loop"\n // when *both* conditions are met!\n ASSERT(preErrorSymbol === 0, "line 1194");\n if (recovering === 0) {\n break;\n }\n continue;\n\n // reduce:\n case 2:\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n // signal end of error recovery loop AND end of outer parse loop\n action = 3;\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (sp >= 0 && typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n sp = -2; // magic number: signal outer "fast parse loop" ACCEPT state that we already have a properly set up `retval` parser return value.\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n\n // should we also break out of the regular/outer parse loop,\n // i.e. did the parser already produce a parse result in here?!\n // *or* did we hit an unsupported parse state, to be handled\n // in the `switch/default` code further below?\n ASSERT(action !== 2, "line 1272");\n if (!action || action === 1) {\n continue;\n }\n }\n\n//_handle_error_no_recovery: // run this code when the grammar does not include any error recovery rules\n\n // handle parse error\n if (!action) {\n var errStr;\n var errSymbolDescr = (this.describeSymbol(symbol) || symbol);\n var expected = this.collect_expected_token_set(state);\n\n // Report error\n if (typeof lexer.yylineno === \'number\') {\n errStr = \'Parse error on line \' + (lexer.yylineno + 1) + \': \';\n } else {\n errStr = \'Parse error: \';\n }\n if (typeof lexer.showPosition === \'function\') {\n errStr += \'\\n\' + lexer.showPosition(79 - 10, 10) + \'\\n\';\n }\n if (expected.length) {\n errStr += \'Expecting \' + expected.join(\', \') + \', got unexpected \' + errSymbolDescr;\n } else {\n errStr += \'Unexpected \' + errSymbolDescr;\n }\n // we cannot recover from the error!\n p = this.constructParseErrorInfo(errStr, null, expected, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n\n//_handle_error_end_of_section: // this concludes the error recovery / no error recovery code section choice above\n\n }\n\n if (yydebug) yydebug(\'::: MAIN CYCLE action: \' + (action === 1 ? \'shift token \' + symbol + \' (then go to state \' + newState + \')\' : action === 2 ? \'reduce by rule: \' + newState + (function __print_rule(nt, state) {\n if (!nt || !nt.states || !nt.rules)\n return \'\';\n var rulename = nt.states[state];\n var rulespec = nt.rules[rulename][state];\n return \' (\' + rulespec.symbol + \' := \' + rulespec.handle + \')\';\n })(this.nonterminals_, newState) : action === 3 ? \'accept\' : \'???unexpected???\'), { action: action, newState: newState, recovering: recovering, symbol: symbol });\n\n switch (action) {\n // catch misc. parse failures:\n default:\n // this shouldn\'t happen, unless resolve defaults are off\n if (action instanceof Array) {\n p = this.constructParseErrorInfo(\'Parse Error: multiple actions possible at state: \' + state + \', token: \' + symbol, null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n }\n // Another case of better safe than sorry: in case state transitions come out of another error recovery process\n // or a buggy LUT (LookUp Table):\n p = this.constructParseErrorInfo(\'Parsing halted. No viable error recovery approach available due to internal system failure.\', null, null, false);\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n break;\n\n // shift:\n case 1:\n stack[sp] = symbol;\n vstack[sp] = lexer.yytext;\n lstack[sp] = copy_yylloc(lexer.yylloc);\n sstack[sp] = newState; // push state\n\n ++sp;\n symbol = 0;\n\n ASSERT(preErrorSymbol === 0, "line 1352"); // normal execution / no error\n ASSERT(recovering === 0, "line 1353"); // normal execution / no error\n\n // Pick up the lexer details for the current symbol as that one is not \'look-ahead\' any more:\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n continue;\n\n // reduce:\n case 2:\n ASSERT(preErrorSymbol === 0, "line 1364"); // normal execution / no error\n ASSERT(recovering === 0, "line 1365"); // normal execution / no error\n\n this_production = this.productions_[newState - 1]; // `this.productions_[]` is zero-based indexed while states start from 1 upwards...\n yyrulelen = this_production[1];\n\n if (yydebug) yydebug(\'~~~ REDUCE: \', { pop_size: yyrulelen, newState: newState, recovering: recovering, symbol: symbol });\n\n r = this.performAction.call(yyval, yytext, yyleng, yylineno, yyloc, newState, sp - 1, yyrulelen, vstack, lstack, stack, sstack);\n\n if (typeof r !== \'undefined\') {\n retval = r;\n break;\n }\n\n // pop off stack\n sp -= yyrulelen;\n\n // don\'t overwrite the `symbol` variable: use a local var to speed things up:\n var ntsymbol = this_production[0]; // push nonterminal (reduce)\n stack[sp] = ntsymbol;\n vstack[sp] = yyval.$;\n lstack[sp] = yyval._$;\n // goto new state = table[STATE][NONTERMINAL]\n newState = table[sstack[sp - 1]][ntsymbol];\n sstack[sp] = newState;\n ++sp;\n if (yydebug) yydebug(\'REDUCED: \', { newState: newState, recovering: recovering, symbol: symbol });\n continue;\n\n // accept:\n case 3:\n if (sp !== -2) {\n retval = true;\n // Return the `$accept` rule\'s `$$` result, if available.\n //\n // Also note that JISON always adds this top-most `$accept` rule (with implicit,\n // default, action):\n //\n // $accept: $end\n // %{ $$ = $1; @$ = @1; %}\n //\n // which, combined with the parse kernel\'s `$accept` state behaviour coded below,\n // will produce the `$$` value output of the rule as the parse result,\n // IFF that result is *not* `undefined`. (See also the parser kernel code.)\n //\n // In code:\n //\n // %{\n // @$ = @1; // if location tracking support is included\n // if (typeof $1 !== \'undefined\')\n // return $1;\n // else\n // return true; // the default parse result if the rule actions don\'t produce anything\n // %}\n sp--;\n if (typeof vstack[sp] !== \'undefined\') {\n retval = vstack[sp];\n }\n }\n break;\n }\n\n // break out of loop: we accept or fail with error\n break;\n }\n } catch (ex) {\n // report exceptions through the parseError callback too, but keep the exception intact\n // if it is a known parser or lexer error which has been thrown by parseError() already:\n if (ex instanceof this.JisonParserError) {\n throw ex;\n }\n else if (lexer && typeof lexer.JisonLexerError === \'function\' && ex instanceof lexer.JisonLexerError) {\n throw ex;\n }\n\n p = this.constructParseErrorInfo(\'Parsing aborted due to exception.\', ex, null, false);\n retval = false;\n r = this.parseError(p.errStr, p, this.JisonParserError);\n if (typeof r !== \'undefined\') {\n retval = r;\n }\n } finally {\n retval = this.cleanupAfterParse(retval, true, true);\n this.__reentrant_call_depth--;\n } // /finally\n\n return retval;\n}\n'; // --- END parser kernel --- @@ -24703,7 +24645,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi DEBUG: false, go_: function go_(productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -24818,7 +24760,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -24834,7 +24776,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -24845,7 +24787,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -24873,7 +24815,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { diff --git a/dist/jison-umd.js b/dist/jison-umd.js index 1defdd6bc..666a9e2b4 100644 --- a/dist/jison-umd.js +++ b/dist/jison-umd.js @@ -1,13 +1,13 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('@gerhobbelt/ast-util')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5', '@gerhobbelt/ast-util'], factory) : - (global.jison = factory(global.fs,global.path,global.recast,global.assert,global.XRegExp,global.json5,global.astUtils)); -}(this, (function (fs,path,recast,assert,XRegExp,json5,astUtils) { 'use strict'; + (global.jison = factory(global.fs,global.path,global.recast,global.assert$1,global.XRegExp,global.json5,global.astUtils)); +}(this, (function (fs,path,recast,assert$1,XRegExp,json5,astUtils) { 'use strict'; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; -assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; +assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; astUtils = astUtils && astUtils.hasOwnProperty('default') ? astUtils['default'] : astUtils; @@ -166,6 +166,16 @@ function dquote$1(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -272,6 +282,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -316,13 +327,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -401,15 +412,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -682,10 +703,7 @@ var setMixin = { var Set = typal.construct(setMixin); -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1228,7 +1246,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1278,7 +1297,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1436,104 +1455,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4500,14 +4522,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4613,8 +4635,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -5232,7 +5253,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -5242,13 +5262,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5888,13 +5911,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5907,7 +5929,7 @@ yyError: 1 }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7537,7 +7559,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9185,7 +9206,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -9199,7 +9220,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -9208,7 +9229,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9397,7 +9418,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9666,9 +9687,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9821,8 +9842,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9837,7 +9858,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9960,6 +9981,14 @@ var version$1 = '0.6.1-215'; // require('./package. +function chkBugger$3(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -10151,7 +10180,7 @@ function autodetectAndConvertToJSONformat$1(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -10159,7 +10188,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -10240,6 +10269,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$3(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10386,7 +10416,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10443,7 +10473,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10498,7 +10528,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10544,7 +10574,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10635,7 +10665,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10672,7 +10702,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10740,7 +10770,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10787,7 +10817,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -11000,7 +11030,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures$1(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -11029,9 +11059,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$3(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -11098,11 +11130,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -11113,7 +11145,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -11123,7 +11155,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -11136,8 +11168,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -11148,8 +11180,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12459,6 +12491,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$3(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$2` return ${getRegExpLexerPrototype()}; `))(); @@ -12570,6 +12603,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12728,6 +12762,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12800,9 +12835,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12846,8 +12881,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { @@ -13231,7 +13266,7 @@ RegExpLexer.camelCase = helpers.camelCase; RegExpLexer.mkIdentifier = mkIdentifier$3; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -13762,7 +13797,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -13812,7 +13848,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13854,104 +13890,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 11, @@ -14904,13 +14943,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -14922,7 +14960,7 @@ parse: function parse(input) { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -17094,10 +17132,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$2; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -17640,7 +17675,8 @@ var parser$2 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -17690,7 +17726,7 @@ var parser$2 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -17842,104 +17878,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } + + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ s$1, @@ -20985,14 +21024,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$2 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$2; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -21098,8 +21137,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -21717,7 +21755,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -21727,13 +21764,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -22373,13 +22413,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -22392,7 +22431,7 @@ yyError: 1 }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -24022,7 +24061,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -26047,6 +26085,14 @@ var version = '0.6.1-215'; var devDebug = 0; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + // WARNING: this regex MUST match the regex for `ID` in ebnf-parser::bnf.l jison language lexer spec! (`ID = [{ALPHA}]{ALNUM}*`) // // This is the base XRegExp ID regex used in many places; this should match the ID macro definition in the EBNF/BNF parser et al as well! @@ -26068,6 +26114,7 @@ const defaultJisonOptions = { outputDebugTables: false, noDefaultResolve: false, defaultActionMode: ["classic", "merge"], // {classic, ast, none, skip}, {classic, ast, merge, none, skip} + testCompileActionCode: "parser:*,lexer:*", noTryCatch: false, hasPartialLrUpgradeOnConflict: true, errorRecoveryTokenDiscardCount: 3, @@ -26095,7 +26142,7 @@ const defaultJisonOptions = { ranges: undefined, showSource: false, reportStats: false, - exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only) + exportAST: false, // output grammar in JSON / JSON5 format (CLI version of JISON only); this will be a copy of `grammar` prettyCfg: true, // use `prettier` (or not) to (re)format the generated parser code. // internal analysis flags which MAY be forced by special %options @@ -26465,8 +26512,8 @@ function each(obj, func) { // This was Set.union() but it's not about *Set* at all: it is purely *Array* oriented! function union(a, b) { - assert(Array.isArray(a)); - assert(Array.isArray(b)); + assert$1(Array.isArray(a)); + assert$1(Array.isArray(b)); // Naive indexOf()-based scanning delivers a faster union() // (which takes the brunt of the load for large grammars): // for examples/jscore this drops 13.2 seconds down to @@ -26729,13 +26776,26 @@ generator.constructor = function Jison_Generator(grammar, optionalLexerSection, // source included in semantic action execution scope if (grammar.actionInclude) { if (typeof grammar.actionInclude === 'function') { - grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, ''); + // Also cope with Arrow Functions (and inline those as well?). + // See also https://github.com/zaach/jison-lex/issues/23 + var action = String(grammar.actionInclude); + chkBugger(action); + if (action.match(/^\s*function\s*\(\)\s*\{/)) { + action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { + // () => 'TOKEN' --> return 'TOKEN' + action = action.replace(/^\s*\(\)\s*=>/, 'return '); + } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*\{/)) { + // () => { statements } --> statements (ergo: 'inline' the given function) + action = action.replace(/^\s*\(\)\s*=>[\s\r\n]*\{/, '').replace(/\}\s*$/, ''); + } + grammar.actionInclude = action; } this.actionInclude = grammar.actionInclude; } this.moduleInclude = grammar.moduleInclude || ''; this.moduleInit = grammar.moduleInit || []; - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); this.DEBUG = !!this.options.debug; this.enableDebugLogs = !!options.enableDebugLogs; @@ -27031,21 +27091,21 @@ generator.signalUnusedProductions = function () { for (i = 0, len = nonterminals.length; i < len; i++) { nt = nonterminals[i]; - assert(nt.symbol); + assert$1(nt.symbol); mark[nt.symbol] = false; } // scan & mark all visited productions function traverseGrammar(nt) { - assert(nt); - assert(nt.symbol); + assert$1(nt); + assert$1(nt.symbol); mark[nt.symbol] = true; var prods = nt.productions; - assert(prods); + assert$1(prods); prods.forEach(function (p) { - assert(p.symbol === nt.symbol); - assert(p.handle); + assert$1(p.symbol === nt.symbol); + assert$1(p.handle); var rhs = p.handle; if (devDebug > 0) { Jison.print('traverse / mark: ', nt.symbol, ' --> ', rhs); @@ -27053,7 +27113,7 @@ generator.signalUnusedProductions = function () { for (var j = 0, len = rhs.length; j < len; j++) { var sym = rhs[j]; - assert(!sym ? !nonterminals[sym] : true); + assert$1(!sym ? !nonterminals[sym] : true); if (nonterminals[sym] && !mark[sym]) { traverseGrammar(nonterminals[sym]); } @@ -27066,12 +27126,12 @@ generator.signalUnusedProductions = function () { // now any production which is not yet marked is *unused*: for (sym in mark) { nt = nonterminals[sym]; - assert(nt); + assert$1(nt); var prods = nt.productions; - assert(prods); + assert$1(prods); var in_use = mark[sym]; prods.forEach(function (p) { - assert(p); + assert$1(p); if (in_use) { p.reachable = true; } else { @@ -27400,7 +27460,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm this.descriptions_ = descriptions_; this.productions_ = productions_; - assert(this.productions === productions); + assert$1(this.productions === productions); // Cope with literal symbols in the string, including *significant whitespace* tokens @@ -27423,7 +27483,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm var pos = pos1; var marker = "'"; if (pos < 0) { - assert(pos2 >= 0); + assert$1(pos2 >= 0); pos = pos2; marker = '"'; } else if (pos >= 0 && pos2 >= 0 && pos2 < pos) { @@ -27503,12 +27563,12 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } - assert(handle.length === 3 ? typeof handle[1] === 'string' : true); + assert$1(handle.length === 3 ? typeof handle[1] === 'string' : true); if (typeof handle[1] === 'string') { // semantic action specified action = handle[1]; @@ -27537,8 +27597,8 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm if (rhs[i] === 'error') { hasErrorRecovery = true; } - assert(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); - assert(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); + assert$1(bnf[rhs[i]] ? symbols_[rhs[i]] : true, 'all nonterminals must already exist in the symbol table'); + assert$1(rhs[i] ? symbols_[rhs[i]] : true, 'all symbols (terminals and nonterminals) must already exist in the symbol table'); //addSymbol(rhs[i]); } } @@ -27546,7 +27606,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm r = new Production(symbol, rhs, productions.length + 1, aliased, action); // set precedence - assert(r.precedence === 0); + assert$1(r.precedence === 0); if (precedence_override) { r.precedence = precedence_override.spec.precedence; } @@ -27779,8 +27839,8 @@ function analyzeFeatureUsage(sourcecode, feature, threshold) { function mkParserFeatureHash(self) { - assert(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus - assert(self.options.exportSourceCode); + assert$1(self.options.exportAllTables); // check that this function isn't called too early in the process or the hash will be bogus + assert$1(self.options.exportSourceCode); var h = [ self.actionsAreAllDefault, self.actionsUseLocationAssignment, @@ -27812,7 +27872,8 @@ function mkParserFeatureHash(self) { self.options.hasPartialLrUpgradeOnConflict, self.options.lexerErrorsAreRecoverable, self.options.moduleType, - self.options.defaultActionMode.join(','), + self.options.defaultActionMode, + self.options.testCompileActionCode, self.options.noDefaultResolve, self.options.noMain, self.options.moduleMain, @@ -27823,11 +27884,15 @@ function mkParserFeatureHash(self) { self.options.parserErrorsAreRecoverable, self.options.tokenStack, self.options.type, + self.options.moduleName, + self.options.parseParams, + self.options.ranges, + self.options.prettyCfg, '======================================', self.performAction, '======================================', ]; - return h.join(','); + return JSON.stringify(h); } generator.buildProductionActions = function buildProductionActions() { @@ -27857,8 +27922,8 @@ generator.buildProductionActions = function buildProductionActions() { }); // and COPY the `moduleInit` array, after preprocessing the individual COPIES: var moduleInit = this.moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); return { qualifier: chunk.qualifier, include: preprocessActionCode(chunk.include) @@ -27867,7 +27932,7 @@ generator.buildProductionActions = function buildProductionActions() { }) }; }); - assert(Array.isArray(moduleInit)); + assert$1(Array.isArray(moduleInit)); // We potentially need multiple (2+) rounds to produce the correct actions // as userland action code determines whether the default actions should @@ -27933,8 +27998,7 @@ generator.buildProductionActions = function buildProductionActions() { function __b0rk_on_internal_failure(str) { var hash = yyparser.constructParseErrorInfo(str, null, null, false); - var r = yyparser.parseError(str, hash, yyparser.JisonParserError); - return r; + return yyparser.parseError(str, hash, yyparser.JisonParserError); } return __b0rk_on_internal_failure("internal parser failure: resolving unlisted state: " + yystate);` @@ -28059,8 +28123,8 @@ generator.buildProductionActions = function buildProductionActions() { this.actionsUseYYMERGELOCATIONINFO = this.actionsUseYYMERGELOCATIONINFO || analyzeFeatureUsage(moduleInclude, /\.yyMergeLocationInfo\b/g, 0); moduleInit.forEach(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); var moduleInclude = chunk.include; //self.actionsUseYYLENG = self.actionsUseYYLENG || analyzeFeatureUsage(moduleInclude, /\byyleng\b/g, 0); @@ -28199,6 +28263,7 @@ generator.buildProductionActions = function buildProductionActions() { hasErrorRecovery: this.hasErrorRecovery, hasErrorReporting: this.hasErrorReporting, defaultActionMode: this.options.defaultActionMode, + testCompileActionCode: this.options.testCompileActionCode, noTryCatch: this.options.noTryCatch, }); } @@ -28210,12 +28275,12 @@ generator.buildProductionActions = function buildProductionActions() { // the other code chunks specified in the grammar file. this.moduleInclude = postprocessActionCode(moduleInclude); this.moduleInit = moduleInit.map(function (chunk) { - assert(chunk.qualifier); - assert(typeof chunk.include === 'string'); + assert$1(chunk.qualifier); + assert$1(typeof chunk.include === 'string'); chunk.include = postprocessActionCode(chunk.include); return chunk; }); - assert(Array.isArray(this.moduleInit)); + assert$1(Array.isArray(this.moduleInit)); // add helper methods to `this.moduleInit` for later use by our code generator: moduleInit = this.moduleInit; @@ -28343,8 +28408,8 @@ generator.buildProductionActions = function buildProductionActions() { var action = preprocessActionCode(handle.action || ''); var rule4msg = handle.symbol + ': ' + rhs.join(' '); - assert(typeof handle.id === 'number'); - assert(handle.id >= 0); + assert$1(typeof handle.id === 'number'); + assert$1(handle.id >= 0); stateHasAction[handle.id] = true; // before anything else, replace direct symbol references, e.g. #NUMBER# when there's a %token NUMBER for your grammar. @@ -28530,7 +28595,7 @@ generator.buildProductionActions = function buildProductionActions() { var m = source.match(assignment_re); if (m) { // check the closure exists in the regex: m[1] is filled with its content: - assert(m[1] != null); + assert$1(m[1] != null); prelude = m[1]; } // now check if there's any mention of the feature before its first @@ -28833,7 +28898,8 @@ generator.createLexer = function createLexer() { }; // no-op. implemented in debug mixin -generator.trace = function no_op_trace() { }; +generator.trace = (new Function('', 'function no_op_trace() { }\nreturn no_op_trace;'))(); +//generator.trace.name = 'no_op_trace'; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); @@ -28927,20 +28993,27 @@ generator.reportGrammarInformation = function reportGrammarInformation() { }; +// --- START of debugTraceSrc chunk --- +const debugTraceSrc = ` +function debug_trace() { + if (typeof Jison !== 'undefined' && Jison.print) { + Jison.print.apply(null, arguments); + } else if (typeof print !== 'undefined') { + print.apply(null, arguments); + } else if (typeof console !== 'undefined' && console.log) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(''); // prevent \`%.\` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args + console.log.apply(null, args); + } +} +`; +// --- END of debugTraceSrc chunk --- + // Generator debug mixin var generatorDebug = { - trace: function debug_trace() { - if (typeof Jison !== 'undefined' && Jison.print) { - Jison.print.apply(null, arguments); - } else if (typeof print !== 'undefined') { - print.apply(null, arguments); - } else if (typeof console !== 'undefined' && console.log) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(''); // prevent `%.` printf-style expansions; see https://nodejs.org/api/console.html#console_console_log_data_args - console.log.apply(null, args); - } - }, + trace: (new Function('', debugTraceSrc + ` + return debug_trace;`))(), beforeprocessGrammar: function () { this.trace('Processing grammar.'); }, @@ -28984,7 +29057,7 @@ lookaheadMixin.displayFollowSets = function displayFollowSets() { if (!symfollowdbg[flw][key]) { symfollowdbg[flw][key] = 1; } else { - assert(0); + assert$1(0); symfollowdbg[flw][key]++; } }); @@ -29034,7 +29107,7 @@ lookaheadMixin.followSets = function followSets() { set = self.first(part); if (self.nullable(part) && bool) { - assert(nonterminals[production.symbol].follows); + assert$1(nonterminals[production.symbol].follows); set.push.apply(set, nonterminals[production.symbol].follows); } } @@ -29437,7 +29510,7 @@ lrGeneratorMixin.parseTable = function lrParseTable(itemSets) { // find shift and goto actions if (item.markedSymbol === stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; - assert(gotoState); + assert$1(gotoState); if (nonterminals[stackSymbol]) { // store state to go to after a reduce state[self.symbols_[stackSymbol]] = gotoState; @@ -29581,7 +29654,7 @@ function findDefaults(states, hasErrorRecovery) { var gotos = {}; for (sym in state) { - assert({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! + assert$1({}.hasOwnProperty.call(state, sym)); // it this isn't true, the last part of this function won't work! // keep state rows where there's an error recovery state: if (sym === 2 /* TERROR */) { return; @@ -30188,8 +30261,8 @@ lrGeneratorMixin.generateESModule = function generateESModule(opt) { var exportMain = ''; var invokeMain = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); out.push(rmCommonWS` @@ -30242,8 +30315,8 @@ generatorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { var moduleName = opt.moduleName; var main = ''; if (!opt.noMain) { - var moduleNameAsCode = String(opt.moduleMain || commonjsMain); - var moduleImportsAsCode = String(opt.moduleMainImports || commonjsMainImports); + var moduleNameAsCode = String(opt.moduleMain || commonJsMain); + var moduleImportsAsCode = String(opt.moduleMainImports || commonJsMainImports); main = rmCommonWS` @@ -30907,7 +30980,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var errorClassCode = this.generateErrorClass(); var exportDest = this.options.exportAllTables; - assert(exportDest); + assert$1(exportDest); // store the parse tables: exportDest.parseTable = this.table; @@ -30915,7 +30988,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { exportDest.parseProductions = this.productions_; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); var tableCode; switch (this.options.compressTables | 0) { @@ -31127,7 +31200,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { var p = lst[idx]; if (p) { if (p.symbol + ' : ' + p.handle === chk) { - assert(rv.state === -1); + assert$1(rv.state === -1); rv.state = idx; break; } @@ -31141,7 +31214,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { for (idx in pr) { var bprod = pr[idx]; if (bprod.symbol + ' : ' + bprod.handle === chk) { - assert(rv.base_state === -1); + assert$1(rv.base_state === -1); rv.base_state = bprod.state; if (patch_base) { bprod.newg_states = (bprod.newg_states || []); @@ -31275,6 +31348,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleMainImports: 1, noDefaultResolve: 1, defaultActionMode: 1, + testCompileActionCode: 1, noTryCatch: 1, hasPartialLrUpgradeOnConflict: 0, compressTables: 1, @@ -31374,7 +31448,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { // // Options: // - // default action mode: ............. ${this.options.defaultActionMode.join(',')} + // default action mode: ............. ${JSON.stringify(this.options.defaultActionMode)} + // test-compile action mode: ........ ${JSON.stringify(this.options.testCompileActionCode)} // try..catch: ...................... ${!this.options.noTryCatch} // default resolve on conflict: ..... ${!this.options.noDefaultResolve} // on-demand look-ahead: ............ ${this.onDemandLookahead} @@ -31441,11 +31516,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { 'terminal_descriptions_: ' + descrLst : [] ).concat([ - String(define_parser_APIs_1) - .replace(/^[\s\S]+?return \{/, '') - .replace(/\};[s\r\n]+\}\s*$/, '') - .replace(/^ /mg, '') - .trim(), + define_parser_APIs_1.trim(), 'productions_: ' + tableCode.productionsCode ]).concat( String(this.performAction).trim() !== '' ? @@ -31476,7 +31547,7 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { moduleCode += '\n};'; var exportSourceCode = this.options.exportSourceCode; - assert(exportSourceCode); + assert$1(exportSourceCode); exportSourceCode.parserChunks = { initCode: expandConstantsInGeneratedCode(initCode.join('\n'), this), commonCode: expandConstantsInGeneratedCode(commonCode.join('\n'), this), @@ -31492,8 +31563,8 @@ lrGeneratorMixin.generateModule_ = function generateModule_() { lrGeneratorMixin.generateErrorClass = function () { // --- START parser error class --- - -var prelude = `// See also: + const prelude = ` +// See also: // http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508 // but we keep the prototype.constructor and prototype.name assignment lines too for compatibility // with userland code which might access the derived class in a 'classic' way. @@ -31542,8 +31613,8 @@ if (typeof Object.setPrototypeOf === 'function') { JisonParserError.prototype = Object.create(Error.prototype); } JisonParserError.prototype.constructor = JisonParserError; -JisonParserError.prototype.name = 'JisonParserError';`; - +JisonParserError.prototype.name = 'JisonParserError'; +`; // --- END parser error class --- return { @@ -31572,6 +31643,18 @@ lrGeneratorMixin.generateTableCode0 = function (table, defaultActions, productio }; }; +// Function that extends an object with the given value for all given keys +// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } +var compressor1ObjectCode = ` +function x(k, v, o) { + o = o || {}; + for (var l = k.length; l--; ) { + o[k[l]] = v; + } + return o; +} +`; + // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productions) { var tableCode = JSON.stringify(table, null, 2); @@ -31662,7 +31745,7 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio // (tiny grammars don't have much state duplication, so this shaves off // another couple bytes off the generated output) if (usesCompressor) { - prelude.push(createObjectCode.toString().replace('createObjectCode', 'x')); + prelude.push(compressor1ObjectCode); prelude.push(''); } @@ -31680,16 +31763,6 @@ lrGeneratorMixin.generateTableCode1 = function (table, defaultActions, productio }; }; -// Function that extends an object with the given value for all given keys -// e.g., x([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 } -function createObjectCode(k, v, o) { - o = o || {}; - for (var l = k.length; l--; ) { - o[k[l]] = v; - } - return o; -} - // Generate code that represents the specified parser table lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productions) { if (this.options.noDefaultResolve && this.conflicts > 0) { @@ -31811,10 +31884,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var prod = table[i]; len_col.push(prod.length); - assert(prod.length <= 2); - assert(prod.length > 0); + assert$1(prod.length <= 2); + assert$1(prod.length > 0); // and the special knowledge about the productions[] table: - assert(prod.length === 2); + assert$1(prod.length === 2); pop_col.push(prod[0]); rule_col.push(prod[1]); } @@ -31844,7 +31917,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio idx_col.push(i); // and the special knowledge about the defaultActions[] table: - assert(typeof prod === 'number'); + assert$1(typeof prod === 'number'); goto_col.push(prod); } @@ -31885,8 +31958,8 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var slot = hashtable[symbol]; if (slot && slot.length) { // array type slot: - assert(slot.length === 2 || slot.length === 1); - assert(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); + assert$1(slot.length === 2 || slot.length === 1); + assert$1(slot.length === 1 ? slot[0] === 3 /* $accept */ : true); type_col.push(slot.length); if (slot.length > 1) { mode_col.push(slot[0]); @@ -31899,7 +31972,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio state_col.push(slot); //next_col.push(slot); } else { - assert(0); + assert$1(0); type_col.push(666); state_col.push((typeof slot) + state + '/' + symbol); //next_col.push((typeof slot) + state + '/' + symbol); @@ -32068,7 +32141,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio var productionsDef = analyzeTableForCompression(productions); - var bp_code_container = ` + const bp_code_container = ` // helper: reconstruct the productions[] table function bp(s) { var rv = []; @@ -32084,7 +32157,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bda_code_container = ` + const bda_code_container = ` // helper: reconstruct the defaultActions[] table function bda(s) { var rv = {}; @@ -32098,7 +32171,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var bt_code_container = ` + const bt_code_container = ` // helper: reconstruct the 'goto' table function bt(s) { var rv = []; @@ -32138,7 +32211,7 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio } `; - var c_s_u_code_container = ` + const c_s_u_code_container = ` // helper: runlength encoding with increment step: code, length: step (default step = 0) // \`this\` references an array function s(c, l, a) { @@ -32217,8 +32290,10 @@ lrGeneratorMixin.generateTableCode2 = function (table, defaultActions, productio }; }; +// --- START of commonJsMain chunk --- +// // default main method for generated commonjs modules -const commonjsMain = ` +const commonJsMain = ` function (args) { // When the parser comes with its own \`main\` function, then use that one: if (typeof exports.parser.main === 'function') { @@ -32243,9 +32318,11 @@ function (args) { rv = dst; } return dst; -}`; +} +`; +// --- END of commonJsMain chunk --- -const commonjsMainImports = ` +const commonJsMainImports = ` var fs = require('fs'); var path = require('path'); `; @@ -32314,6 +32391,7 @@ generatorMixin.createParser = function createParser() { `; var p = code_exec(sourcecode, function generated_code_exec_wrapper_jison(sourcecode) { //console.log("===============================PARSER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var rv = eval(sourcecode); return rv; }, mkStdOptions(this.options, { @@ -32321,37 +32399,37 @@ generatorMixin.createParser = function createParser() { throwErrorOnCompileFailure: true }), "parser"); - assert(typeof p === 'object'); - assert(typeof p.parse === 'function'); - assert(typeof p.parser === 'undefined'); - assert(typeof p.Parser === 'function'); - assert(typeof p.yy === 'object'); - assert(typeof p.EOF === 'number'); - assert(typeof p.TERROR === 'number'); + assert$1(typeof p === 'object'); + assert$1(typeof p.parse === 'function'); + assert$1(typeof p.parser === 'undefined'); + assert$1(typeof p.Parser === 'function'); + assert$1(typeof p.yy === 'object'); + assert$1(typeof p.EOF === 'number'); + assert$1(typeof p.TERROR === 'number'); // assert(typeof p.trace === 'function'); - assert(typeof p.JisonParserError === 'function'); - assert(typeof p.quoteName === 'function'); - assert(typeof p.originalQuoteName === 'function'); - assert(typeof p.describeSymbol === 'function'); - assert(typeof p.symbols_ === 'object'); - assert(typeof p.terminals_ === 'object'); + assert$1(typeof p.JisonParserError === 'function'); + assert$1(typeof p.quoteName === 'function'); + assert$1(typeof p.originalQuoteName === 'function'); + assert$1(typeof p.describeSymbol === 'function'); + assert$1(typeof p.symbols_ === 'object'); + assert$1(typeof p.terminals_ === 'object'); // assert(typeof p.nonterminals === 'undefined'); // assert(typeof p.terminal_descriptions_ === 'undefined'); // assert(typeof p.productions_ === 'object'); - assert(typeof p.performAction === 'function'); - assert(typeof p.table === 'object'); + assert$1(typeof p.performAction === 'function'); + assert$1(typeof p.table === 'object'); // assert(typeof p.defaultActions === 'object'); - assert(typeof p.parseError === 'function'); + assert$1(typeof p.parseError === 'function'); // assert(typeof p.yyError === 'undefined'); // assert(typeof p.yyRecovering === 'undefined'); // assert(typeof p.yyErrOk === 'undefined'); // assert(typeof p.yyClearIn === 'undefined'); - assert(typeof p.constructParseErrorInfo === 'object'); - assert(typeof p.originalParseError === 'function'); - assert(typeof p.options === 'object'); - assert(typeof p.cleanupAfterParse === 'object'); - assert(typeof p.yyMergeLocationInfo === 'object'); - assert(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); + assert$1(typeof p.constructParseErrorInfo === 'object'); + assert$1(typeof p.originalParseError === 'function'); + assert$1(typeof p.options === 'object'); + assert$1(typeof p.cleanupAfterParse === 'object'); + assert$1(typeof p.yyMergeLocationInfo === 'object'); + assert$1(typeof p.lexer === 'object' || typeof p.lexer === 'undefined'); // for debugging p.productions = this.productions; @@ -32388,6 +32466,7 @@ parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; +// --- START parser Error class chunk --- const parseErrorSourceCode = ` function parseError(str, hash, ExceptionClass) { if (hash.recoverable) { @@ -32404,8 +32483,11 @@ function parseError(str, hash, ExceptionClass) { } throw new ExceptionClass(str, hash); } -}`; // END of parseErrorSourceCode chunk +} +`; +// --- END of parseErrorSourceCode chunk --- +chkBugger(parseErrorSourceCode); parser.parseError = lrGeneratorMixin.parseError = eval(parseErrorSourceCode + '\n\nparseError;'); generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, options) { @@ -32417,123 +32499,125 @@ generatorMixin.createLexer = function createLexer(lexerSpec, input, tokens, opti }; -// wrapper function so we easily stringify the APIs defined inside to code *with comments* +// --- START parser API def chunk --- +// +// One chunk so we can easily stringify the APIs defined here to code *with comments* // in the generated code: -function define_parser_APIs_1() { - return { - TERROR: 2, - EOF: 1, - - // internals: defined here so the object *structure* doesn't get modified by parse() et al, - // thus helping JIT compilers like Chrome V8. - originalQuoteName: null, - originalParseError: null, - cleanupAfterParse: null, - constructParseErrorInfo: null, - yyMergeLocationInfo: null, - - __reentrant_call_depth: 0, // INTERNAL USE ONLY - __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - - // APIs which will be set up depending on user action code analysis: - //yyRecovering: 0, - //yyErrOk: 0, - //yyClearIn: 0, - - // Helper APIs - // ----------- - - // Helper function which can be overridden by user code later on: put suitable quotes around - // literal IDs in a description string. - quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; - }, +const define_parser_APIs_1 = ` + TERROR: 2, + EOF: 1, - // Return the name of the given symbol (terminal or non-terminal) as a string, when available. - // - // Return NULL when the symbol is unknown to the parser. - getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; - } - } - return null; - }, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } - // Return a more-or-less human-readable description of the given symbol, when available, - // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. // - // Return NULL when the symbol is unknown to the parser. - describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } - else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; - }, - - // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // An example of this may be where a rule's action code contains a call like this: // - // The produced list may contain token or token set descriptions instead of the tokens - // themselves to help turning this output into something that easier to read by humans - // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, - // expected terminals and nonterminals is produced. + // parser.getSymbolName(#$) // - // The returned list (array) will not contain any duplicate entries. - collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [ - this.state_descriptions_[state] - ]; + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. - } + } + return null; + }, + + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless \`do_not_describe\` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. } } - return tokenset; } - }; -} + return tokenset; + } +`; +// --- END of define_parser_APIs_1 chunk --- -var api_set = define_parser_APIs_1(); +var api_set = (new Function('', 'return { ' + define_parser_APIs_1 + ' };'))(); for (var api in api_set) { parser[api] = api_set[api]; } // --- START parser kernel --- -parser.parse = `function parse(input, parseParams) { +parser.parse = ` +function parse(input, parseParams) { var self = this; var stack = new Array(128); // token stack: stores token which leads to state at the same index (column storage) var sstack = new Array(128); // state stack: stores states (column storage) @@ -32699,7 +32783,11 @@ parser.parse = `function parse(input, parseParams) { } else { re1 = new XRegExp(' \\"([\\\\p{Alphabetic}_][\\\\p{Alphabetic}\\\\p{Number}_. ]*)\\": ', 'g'); } - js = JSON.stringify(obj, null, 2).replace(re1, ' $1: ').replace(/[\\n\\s]+/g, ' '); + js = JSON.stringify(obj, null, 2) + .replace(re1, ' $1: ') + .replace(/[\\n\\s]+/g, ' ') + // shorten yylloc object dumps too: + .replace(/\\{ first_line: (\\d+), first_column: (\\d+), last_line: (\\d+), last_column: (\\d+)/g, '{L/C: ($1,$2)..($3,$4)'); } catch (ex) { js = String(obj); } @@ -32767,8 +32855,7 @@ parser.parse = `function parse(input, parseParams) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -33419,16 +33506,18 @@ parser.parse = `function parse(input, parseParams) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); + if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } - if (yydebug) yydebug('error recovery rule detected: ', { error_rule_depth: error_rule_depth, error: p.errStr, error_hash: p }); // Protect against overly blunt userland \`parseError\` code which *sets* // the \`recoverable\` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -34004,13 +34093,12 @@ parser.parse = `function parse(input, parseParams) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -34018,7 +34106,8 @@ parser.parse = `function parse(input, parseParams) { } // /finally return retval; -}`; +} +`; // --- END parser kernel --- @@ -34067,7 +34156,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { DEBUG: false, go_: function (productionSymbol, productionHandle) { var stateNum = productionSymbol.split(':')[0]; // grab state # - assert(stateNum == +stateNum); + assert$1(stateNum == +stateNum); stateNum = +stateNum; productionHandle = productionHandle.map(function (rhsElem) { return rhsElem.slice(rhsElem.indexOf(':') + 1); @@ -34187,7 +34276,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, go: function LALR_go(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum; for (var i = 0; i < productionHandle.length; i++) { endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; @@ -34203,7 +34292,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { }, goPath: function LALR_goPath(stateNum, productionHandle, productionSymbol) { - assert(typeof stateNum === 'number'); + assert$1(typeof stateNum === 'number'); var endStateNum = stateNum, t, path$$1 = []; @@ -34214,7 +34303,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { } path$$1.push(t); endStateNum = this.states.item(endStateNum).edges[productionHandle[i]] || endStateNum; - assert(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); + assert$1(t ? typeof this.terms_[t] === 'undefined' || this.terms_[t] === productionHandle[i] : true); this.terms_[t] = productionHandle[i]; } if (devDebug > 0) { @@ -34242,7 +34331,7 @@ var lalr = generator.beget(lookaheadMixin, generatorMixin, lrGeneratorMixin, { if (item.dotPosition === 0) { // new symbols are a combination of state and transition symbol var symbol = i + ':' + item.production.symbol; - assert(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); + assert$1(typeof self.terms_[symbol] === 'undefined' || self.terms_[symbol] === item.production.symbol); self.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) { diff --git a/packages/ebnf-parser/dist/ebnf-parser-cjs-es5.js b/packages/ebnf-parser/dist/ebnf-parser-cjs-es5.js index 5d6d3feb9..3ad8fe693 100644 --- a/packages/ebnf-parser/dist/ebnf-parser-cjs-es5.js +++ b/packages/ebnf-parser/dist/ebnf-parser-cjs-es5.js @@ -86,7 +86,7 @@ var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -238,6 +238,13 @@ function dquote$1(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -328,6 +335,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -367,13 +375,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -437,15 +445,24 @@ var parse2AST = { checkActionBlock: checkActionBlock$1 }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -471,7 +488,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -985,7 +1002,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1747,13 +1765,13 @@ var parser$1 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -1765,7 +1783,7 @@ var parser$1 = { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -3856,10 +3874,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -4385,7 +4400,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -6017,14 +6033,14 @@ var parser = { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -6113,8 +6129,7 @@ var parser = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -6669,14 +6684,15 @@ var parser = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -7172,13 +7188,13 @@ var parser = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -7191,7 +7207,7 @@ var parser = { }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -8790,7 +8806,6 @@ var lexer = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9640,10 +9655,7 @@ var bnf = { }; -// hack: -var assert$3; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -10169,7 +10181,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -11758,14 +11771,14 @@ var parser$3 = { }; var ASSERT; - if (typeof assert$3 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$3; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -11854,8 +11867,7 @@ var parser$3 = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -12410,14 +12422,15 @@ var parser$3 = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -12913,13 +12926,13 @@ var parser$3 = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -12932,7 +12945,7 @@ var parser$3 = { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -14531,7 +14544,6 @@ var lexer$2 = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/ebnf-parser/dist/ebnf-parser-cjs.js b/packages/ebnf-parser/dist/ebnf-parser-cjs.js index 4417e43a8..c6f7695cb 100644 --- a/packages/ebnf-parser/dist/ebnf-parser-cjs.js +++ b/packages/ebnf-parser/dist/ebnf-parser-cjs.js @@ -6,7 +6,7 @@ var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -162,6 +162,16 @@ function dquote$1(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -268,6 +278,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -312,13 +323,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -397,15 +408,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -433,7 +454,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -964,7 +985,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1014,7 +1036,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -1056,104 +1078,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ 11, @@ -2106,13 +2131,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -2124,7 +2148,7 @@ parse: function parse(input) { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -4296,10 +4320,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -4842,7 +4863,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -4892,7 +4914,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -5044,104 +5066,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ s, @@ -8187,14 +8212,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -8300,8 +8325,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -8919,7 +8943,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -8929,13 +8952,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -9575,13 +9601,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -9594,7 +9619,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -11224,7 +11249,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -12351,10 +12375,7 @@ var bnf = { }; -// hack: -var assert$3; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -12897,7 +12918,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -12947,7 +12969,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13105,104 +13127,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 54, @@ -16169,14 +16194,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$3 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$3; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -16282,8 +16307,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -16901,7 +16925,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -16911,13 +16934,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -17557,13 +17583,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -17576,7 +17601,7 @@ yyError: 1 }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -19206,7 +19231,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/ebnf-parser/dist/ebnf-parser-es6.js b/packages/ebnf-parser/dist/ebnf-parser-es6.js index 7f2e73d36..cb4352a99 100644 --- a/packages/ebnf-parser/dist/ebnf-parser-es6.js +++ b/packages/ebnf-parser/dist/ebnf-parser-es6.js @@ -2,7 +2,7 @@ import XRegExp from '@gerhobbelt/xregexp'; import fs from 'fs'; import path from 'path'; import recast from '@gerhobbelt/recast'; -import assert from 'assert'; +import assert$1 from 'assert'; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -158,6 +158,16 @@ function dquote$1(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -264,6 +274,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -308,13 +319,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -393,15 +404,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -429,7 +450,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -960,7 +981,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1010,7 +1032,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -1052,104 +1074,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ 11, @@ -2102,13 +2127,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -2120,7 +2144,7 @@ parse: function parse(input) { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -4292,10 +4316,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -4838,7 +4859,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -4888,7 +4910,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -5040,104 +5062,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ s, @@ -8183,14 +8208,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -8296,8 +8321,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -8915,7 +8939,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -8925,13 +8948,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -9571,13 +9597,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -9590,7 +9615,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -11220,7 +11245,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -12347,10 +12371,7 @@ var bnf = { }; -// hack: -var assert$3; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -12893,7 +12914,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -12943,7 +12965,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13101,104 +13123,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 54, @@ -16165,14 +16190,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$3 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$3; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -16278,8 +16303,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -16897,7 +16921,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -16907,13 +16930,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -17553,13 +17579,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -17572,7 +17597,7 @@ yyError: 1 }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -19202,7 +19227,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/ebnf-parser/dist/ebnf-parser-umd-es5.js b/packages/ebnf-parser/dist/ebnf-parser-umd-es5.js index 341030982..228c27f59 100644 --- a/packages/ebnf-parser/dist/ebnf-parser-umd-es5.js +++ b/packages/ebnf-parser/dist/ebnf-parser-umd-es5.js @@ -79,15 +79,15 @@ var _templateObject = _taggedTemplateLiteral(['\n Maybe you did not corre function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } (function (global, factory) { - (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : global['ebnf-parser'] = factory(global.XRegExp, global.fs, global.path, global.recast, global.assert); -})(undefined, function (XRegExp, fs, path, recast, assert) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : global['ebnf-parser'] = factory(global.XRegExp, global.fs, global.path, global.recast, global.assert$1); +})(undefined, function (XRegExp, fs, path, recast, assert$1) { 'use strict'; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; - assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; + assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -239,6 +239,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // + function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -329,6 +336,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -368,13 +376,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi //import astUtils from '@gerhobbelt/ast-util'; - assert(recast); + assert$1(recast); var types = recast.types; - assert(types); + assert$1(types); var namedTypes = types.namedTypes; - assert(namedTypes); + assert$1(namedTypes); var b = types.builders; - assert(b); + assert$1(b); // //assert(astUtils); @@ -438,15 +446,24 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi checkActionBlock: checkActionBlock$1 }; + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -472,7 +489,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -986,7 +1003,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1748,13 +1766,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -1766,7 +1784,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -3857,10 +3875,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return rv; } - // hack: - var assert$1; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -4386,7 +4401,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -6018,14 +6034,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -6114,8 +6130,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -6670,14 +6685,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -7173,13 +7189,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -7192,7 +7208,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -8791,7 +8807,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -9641,10 +9656,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; - // hack: - var assert$3; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -10170,7 +10182,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -11759,14 +11772,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$3 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$3; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -11855,8 +11868,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -12411,14 +12423,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -12914,13 +12927,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -12933,7 +12946,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -14532,7 +14545,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/ebnf-parser/dist/ebnf-parser-umd.js b/packages/ebnf-parser/dist/ebnf-parser-umd.js index 6f2090b74..839723e52 100644 --- a/packages/ebnf-parser/dist/ebnf-parser-umd.js +++ b/packages/ebnf-parser/dist/ebnf-parser-umd.js @@ -1,14 +1,14 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : - (global['ebnf-parser'] = factory(global.XRegExp,global.fs,global.path,global.recast,global.assert)); -}(this, (function (XRegExp,fs,path,recast,assert) { 'use strict'; + (global['ebnf-parser'] = factory(global.XRegExp,global.fs,global.path,global.recast,global.assert$1)); +}(this, (function (XRegExp,fs,path,recast,assert$1) { 'use strict'; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; -assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; +assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -164,6 +164,16 @@ function dquote$1(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -270,6 +280,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -314,13 +325,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -399,15 +410,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -435,7 +456,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -966,7 +987,8 @@ var parser$1 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1016,7 +1038,7 @@ var parser$1 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$1, yy: {}, options: { @@ -1058,104 +1080,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$1({ pop: u$1([ 11, @@ -2108,13 +2133,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -2126,7 +2150,7 @@ parse: function parse(input) { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -4298,10 +4322,7 @@ function transform(ebnf) { return rv; } -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -4844,7 +4865,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -4894,7 +4916,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -5046,104 +5068,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ s, @@ -8189,14 +8214,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -8302,8 +8327,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -8921,7 +8945,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -8931,13 +8954,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -9577,13 +9603,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -9596,7 +9621,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -11226,7 +11251,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -12353,10 +12377,7 @@ var bnf = { }; -// hack: -var assert$3; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -12899,7 +12920,8 @@ var parser$3 = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -12949,7 +12971,7 @@ var parser$3 = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError$2, yy: {}, options: { @@ -13107,104 +13129,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp$2({ pop: u$2([ 54, @@ -16171,14 +16196,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$3 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$3; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -16284,8 +16309,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -16903,7 +16927,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -16913,13 +16936,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -17559,13 +17585,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -17578,7 +17603,7 @@ yyError: 1 }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -19208,7 +19233,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/ebnf-parser/parser.js b/packages/ebnf-parser/parser.js index 35d363248..cab94a38c 100644 --- a/packages/ebnf-parser/parser.js +++ b/packages/ebnf-parser/parser.js @@ -1,8 +1,5 @@ -// hack: -var assert; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -550,7 +547,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -600,7 +598,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -752,104 +750,107 @@ terminals_: { 46: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ s, @@ -4008,8 +4009,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4636,7 +4636,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4646,13 +4645,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5292,13 +5294,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5311,7 +5312,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -6941,7 +6942,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/ebnf-parser/transform-parser.js b/packages/ebnf-parser/transform-parser.js index f37e5873a..1c0561be3 100644 --- a/packages/ebnf-parser/transform-parser.js +++ b/packages/ebnf-parser/transform-parser.js @@ -1,8 +1,5 @@ -// hack: -var assert; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -535,7 +532,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -585,7 +583,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -627,104 +625,107 @@ terminals_: { 10: "SYMBOL" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 11, @@ -1697,13 +1698,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -1715,7 +1715,7 @@ parse: function parse(input) { }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: diff --git a/packages/helpers-lib/dist/helpers-lib-cjs-es5.js b/packages/helpers-lib/dist/helpers-lib-cjs-es5.js index fdc368410..4c1d566b3 100644 --- a/packages/helpers-lib/dist/helpers-lib-cjs-es5.js +++ b/packages/helpers-lib/dist/helpers-lib-cjs-es5.js @@ -161,6 +161,13 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -251,6 +258,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -360,15 +368,24 @@ var parse2AST = { checkActionBlock: checkActionBlock }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } diff --git a/packages/helpers-lib/dist/helpers-lib-cjs.js b/packages/helpers-lib/dist/helpers-lib-cjs.js index 29add94ea..b6c38c581 100644 --- a/packages/helpers-lib/dist/helpers-lib-cjs.js +++ b/packages/helpers-lib/dist/helpers-lib-cjs.js @@ -161,6 +161,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -267,6 +277,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -396,15 +407,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } diff --git a/packages/helpers-lib/dist/helpers-lib-es6.js b/packages/helpers-lib/dist/helpers-lib-es6.js index 8aff29285..7f8b8f3cb 100644 --- a/packages/helpers-lib/dist/helpers-lib-es6.js +++ b/packages/helpers-lib/dist/helpers-lib-es6.js @@ -157,6 +157,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -263,6 +273,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -392,15 +403,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } diff --git a/packages/helpers-lib/dist/helpers-lib-umd-es5.js b/packages/helpers-lib/dist/helpers-lib-umd-es5.js index 3c4223cc2..5b5a2faa9 100644 --- a/packages/helpers-lib/dist/helpers-lib-umd-es5.js +++ b/packages/helpers-lib/dist/helpers-lib-umd-es5.js @@ -162,6 +162,13 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol // + function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -252,6 +259,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -361,15 +369,24 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol checkActionBlock: checkActionBlock }; + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } diff --git a/packages/helpers-lib/dist/helpers-lib-umd.js b/packages/helpers-lib/dist/helpers-lib-umd.js index 4c7a79f06..8e197cde2 100644 --- a/packages/helpers-lib/dist/helpers-lib-umd.js +++ b/packages/helpers-lib/dist/helpers-lib-umd.js @@ -163,6 +163,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -269,6 +279,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -398,15 +409,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } diff --git a/packages/jison-lex/dist/cli-cjs-es5.js b/packages/jison-lex/dist/cli-cjs-es5.js index efa17abfc..a2f3c1bfa 100644 --- a/packages/jison-lex/dist/cli-cjs-es5.js +++ b/packages/jison-lex/dist/cli-cjs-es5.js @@ -58,7 +58,7 @@ var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var nomnom = _interopDefault(require('@gerhobbelt/nomnom')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var json5 = _interopDefault(require('@gerhobbelt/json5')); @@ -212,6 +212,13 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -302,6 +309,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -341,13 +349,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -411,15 +419,24 @@ var parse2AST = { checkActionBlock: checkActionBlock }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -445,10 +462,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -974,7 +988,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2563,14 +2578,14 @@ var parser = { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2659,8 +2674,7 @@ var parser = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3215,14 +3229,15 @@ var parser = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -3718,13 +3733,13 @@ var parser = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -3737,7 +3752,7 @@ var parser = { }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5336,7 +5351,6 @@ var lexer = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6652,7 +6666,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6666,7 +6680,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6675,7 +6689,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -6859,7 +6873,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7125,9 +7139,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7277,8 +7291,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7293,7 +7307,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7407,6 +7421,13 @@ var code_exec$1 = helpers.exec; var version$1 = '0.6.1-215'; // require('./package.json').version; +function chkBugger$2(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7592,7 +7613,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7600,7 +7621,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7681,6 +7702,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$2(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -7821,7 +7843,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -7878,7 +7900,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -7933,7 +7955,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -7978,7 +8000,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8069,7 +8091,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8106,7 +8128,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8171,7 +8193,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8218,7 +8240,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8351,7 +8373,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8375,6 +8397,7 @@ function RegExpLexer(dict, input, tokens, build_options) { var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec$1(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$2(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8441,11 +8464,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8456,14 +8479,14 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8476,8 +8499,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8488,8 +8511,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8582,6 +8605,7 @@ function getRegExpLexerPrototype() { // --- END lexer kernel --- } +chkBugger$2(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS$1(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8645,6 +8669,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -8803,6 +8828,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -8869,9 +8895,9 @@ function generateModuleBody(opt) { protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -8906,8 +8932,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/cli-cjs.js b/packages/jison-lex/dist/cli-cjs.js index 86a8b49d6..300305feb 100644 --- a/packages/jison-lex/dist/cli-cjs.js +++ b/packages/jison-lex/dist/cli-cjs.js @@ -9,7 +9,7 @@ var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var nomnom = _interopDefault(require('@gerhobbelt/nomnom')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var json5 = _interopDefault(require('@gerhobbelt/json5')); @@ -167,6 +167,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -273,6 +283,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -317,13 +328,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -402,15 +413,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -438,10 +459,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -984,7 +1002,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1034,7 +1053,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1192,104 +1211,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, - -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + EOF: 1, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4256,14 +4278,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4369,8 +4391,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4988,7 +5009,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4998,13 +5018,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5644,13 +5667,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5663,7 +5685,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7293,7 +7315,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -8941,7 +8962,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -8955,7 +8976,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -8964,7 +8985,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9153,7 +9174,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9422,9 +9443,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9577,8 +9598,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9593,7 +9614,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9716,6 +9737,14 @@ var version$1 = '0.6.1-215'; // require('./package. +function chkBugger$2(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -9907,7 +9936,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -9915,7 +9944,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -9996,6 +10025,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$2(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10142,7 +10172,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10199,7 +10229,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10254,7 +10284,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10300,7 +10330,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10391,7 +10421,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10428,7 +10458,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10496,7 +10526,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10543,7 +10573,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10756,7 +10786,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -10785,9 +10815,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$1(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$2(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -10854,11 +10886,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -10869,7 +10901,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -10879,7 +10911,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -10892,8 +10924,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -10904,8 +10936,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12215,6 +12247,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$2(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$1` return ${getRegExpLexerPrototype()}; `))(); @@ -12326,6 +12359,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12484,6 +12518,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12556,9 +12591,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12602,8 +12637,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/cli-es6.js b/packages/jison-lex/dist/cli-es6.js index d371090b5..943842fc1 100644 --- a/packages/jison-lex/dist/cli-es6.js +++ b/packages/jison-lex/dist/cli-es6.js @@ -5,7 +5,7 @@ import fs from 'fs'; import path from 'path'; import nomnom from '@gerhobbelt/nomnom'; import recast from '@gerhobbelt/recast'; -import assert from 'assert'; +import assert$1 from 'assert'; import XRegExp from '@gerhobbelt/xregexp'; import json5 from '@gerhobbelt/json5'; @@ -163,6 +163,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -269,6 +279,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -313,13 +324,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -398,15 +409,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -434,9 +455,6 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - /* parser generated by jison 0.6.1-215 */ /* @@ -980,7 +998,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1030,7 +1049,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1188,104 +1207,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, - -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + EOF: 1, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // An example of this may be where a rule's action code contains a call like this: - // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4252,14 +4274,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -7289,7 +7311,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -8937,7 +8958,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -8951,7 +8972,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -8960,7 +8981,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9149,7 +9170,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9418,9 +9439,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9573,8 +9594,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9589,7 +9610,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9712,6 +9733,14 @@ var version$1 = '0.6.1-215'; // require('./package. +function chkBugger$2(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -9903,7 +9932,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -9911,7 +9940,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -9992,6 +10021,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$2(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10138,7 +10168,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10195,7 +10225,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10250,7 +10280,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10296,7 +10326,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10387,7 +10417,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10424,7 +10454,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10492,7 +10522,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10539,7 +10569,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10752,7 +10782,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -10781,9 +10811,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$1(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$2(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -10850,11 +10882,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -10865,7 +10897,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -10875,7 +10907,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -10888,8 +10920,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -10900,8 +10932,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12211,6 +12243,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$2(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$1` return ${getRegExpLexerPrototype()}; `))(); @@ -12554,9 +12587,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12600,8 +12633,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/cli-umd-es5.js b/packages/jison-lex/dist/cli-umd-es5.js index 2c895a214..c4f584ce4 100644 --- a/packages/jison-lex/dist/cli-umd-es5.js +++ b/packages/jison-lex/dist/cli-umd-es5.js @@ -51,15 +51,15 @@ var _templateObject = _taggedTemplateLiteral(['\n There\'s an error in yo function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } (function (global, factory) { - (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(require('fs'), require('path'), require('@gerhobbelt/nomnom'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/nomnom', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5'], factory) : factory(global.fs, global.path, global.nomnom, global.recast, global.assert, global.XRegExp, global.json5); -})(undefined, function (fs, path, nomnom, recast, assert, XRegExp, json5) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(require('fs'), require('path'), require('@gerhobbelt/nomnom'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/nomnom', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5'], factory) : factory(global.fs, global.path, global.nomnom, global.recast, global.assert$1, global.XRegExp, global.json5); +})(undefined, function (fs, path, nomnom, recast, assert$1, XRegExp, json5) { 'use strict'; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; nomnom = nomnom && nomnom.hasOwnProperty('default') ? nomnom['default'] : nomnom; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; - assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; + assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; @@ -213,6 +213,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // + function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -303,6 +310,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -342,13 +350,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi //import astUtils from '@gerhobbelt/ast-util'; - assert(recast); + assert$1(recast); var types = recast.types; - assert(types); + assert$1(types); var namedTypes = types.namedTypes; - assert(namedTypes); + assert$1(namedTypes); var b = types.builders; - assert(b); + assert$1(b); // //assert(astUtils); @@ -412,15 +420,24 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi checkActionBlock: checkActionBlock }; + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -446,10 +463,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; - // hack: - var assert$1; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -975,7 +989,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2564,14 +2579,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2660,8 +2675,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3216,14 +3230,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -3719,13 +3734,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -3738,7 +3753,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5337,7 +5352,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6653,7 +6667,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6667,7 +6681,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6676,7 +6690,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -6860,7 +6874,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7126,9 +7140,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7278,8 +7292,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7294,7 +7308,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7408,6 +7422,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var version$1 = '0.6.1-215'; // require('./package.json').version; + function chkBugger$2(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7593,7 +7614,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7601,7 +7622,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7682,6 +7703,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$2(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -7822,7 +7844,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -7879,7 +7901,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -7934,7 +7956,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -7979,7 +8001,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8070,7 +8092,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8107,7 +8129,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8172,7 +8194,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8219,7 +8241,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8352,7 +8374,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8376,6 +8398,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec$1(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$2(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8442,11 +8465,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8457,14 +8480,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8477,8 +8500,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8489,8 +8512,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8583,6 +8606,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // --- END lexer kernel --- } + chkBugger$2(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS$1(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8646,6 +8670,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -8804,6 +8829,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -8870,9 +8896,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -8907,8 +8933,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/cli-umd.js b/packages/jison-lex/dist/cli-umd.js index a9bbe5589..650960e5e 100644 --- a/packages/jison-lex/dist/cli-umd.js +++ b/packages/jison-lex/dist/cli-umd.js @@ -4,14 +4,14 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('fs'), require('path'), require('@gerhobbelt/nomnom'), require('@gerhobbelt/recast'), require('assert'), require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5')) : typeof define === 'function' && define.amd ? define(['fs', 'path', '@gerhobbelt/nomnom', '@gerhobbelt/recast', 'assert', '@gerhobbelt/xregexp', '@gerhobbelt/json5'], factory) : - (factory(global.fs,global.path,global.nomnom,global.recast,global.assert,global.XRegExp,global.json5)); -}(this, (function (fs,path,nomnom,recast,assert,XRegExp,json5) { 'use strict'; + (factory(global.fs,global.path,global.nomnom,global.recast,global.assert$1,global.XRegExp,global.json5)); +}(this, (function (fs,path,nomnom,recast,assert$1,XRegExp,json5) { 'use strict'; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; nomnom = nomnom && nomnom.hasOwnProperty('default') ? nomnom['default'] : nomnom; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; -assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; +assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; @@ -169,6 +169,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -275,6 +285,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -319,13 +330,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -404,15 +415,25 @@ var parse2AST = { checkActionBlock, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -440,10 +461,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -986,7 +1004,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1036,7 +1055,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1194,104 +1213,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, - -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + EOF: 1, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4258,14 +4280,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4371,8 +4393,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4990,7 +5011,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -5000,13 +5020,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5646,13 +5669,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5665,7 +5687,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7295,7 +7317,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -8943,7 +8964,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -8957,7 +8978,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -8966,7 +8987,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9155,7 +9176,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9424,9 +9445,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9579,8 +9600,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9595,7 +9616,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9718,6 +9739,14 @@ var version$1 = '0.6.1-215'; // require('./package. +function chkBugger$2(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -9909,7 +9938,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -9917,7 +9946,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -9998,6 +10027,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger$2(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10144,7 +10174,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10201,7 +10231,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10256,7 +10286,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10302,7 +10332,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10393,7 +10423,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10430,7 +10460,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10498,7 +10528,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10545,7 +10575,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10758,7 +10788,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -10787,9 +10817,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec$1(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger$2(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -10856,11 +10888,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -10871,7 +10903,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -10881,7 +10913,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -10894,8 +10926,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -10906,8 +10938,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12217,6 +12249,7 @@ return `{ // --- END lexer kernel --- } +chkBugger$2(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS$1` return ${getRegExpLexerPrototype()}; `))(); @@ -12328,6 +12361,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12486,6 +12520,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12558,9 +12593,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12604,8 +12639,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/regexp-lexer-cjs-es5.js b/packages/jison-lex/dist/regexp-lexer-cjs-es5.js index 52307ab8b..96ef4ae5d 100644 --- a/packages/jison-lex/dist/regexp-lexer-cjs-es5.js +++ b/packages/jison-lex/dist/regexp-lexer-cjs-es5.js @@ -56,7 +56,7 @@ var json5 = _interopDefault(require('@gerhobbelt/json5')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -208,6 +208,13 @@ function dquote(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -298,6 +305,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -337,13 +345,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -407,15 +415,24 @@ var parse2AST = { checkActionBlock: checkActionBlock$1 }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -441,10 +458,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -970,7 +984,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2559,14 +2574,14 @@ var parser = { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2655,8 +2670,7 @@ var parser = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3211,14 +3225,15 @@ var parser = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -3714,13 +3729,13 @@ var parser = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -3733,7 +3748,7 @@ var parser = { }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5332,7 +5347,6 @@ var lexer = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6648,7 +6662,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6662,7 +6676,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6671,7 +6685,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -6855,7 +6869,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7121,9 +7135,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7273,8 +7287,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7289,7 +7303,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7403,6 +7417,13 @@ var code_exec = helpers.exec; var version = '0.6.1-215'; // require('./package.json').version; +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7588,7 +7609,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7596,7 +7617,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7677,6 +7698,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -7817,7 +7839,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -7874,7 +7896,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -7929,7 +7951,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -7974,7 +7996,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8065,7 +8087,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8102,7 +8124,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8167,7 +8189,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8214,7 +8236,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8347,7 +8369,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8371,6 +8393,7 @@ function RegExpLexer(dict, input, tokens, build_options) { var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8437,11 +8460,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8452,14 +8475,14 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8472,8 +8495,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8484,8 +8507,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8578,6 +8601,7 @@ function getRegExpLexerPrototype() { // --- END lexer kernel --- } +chkBugger(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8641,6 +8665,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -8799,6 +8824,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -8865,9 +8891,9 @@ function generateModuleBody(opt) { protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -8902,8 +8928,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/regexp-lexer-cjs.js b/packages/jison-lex/dist/regexp-lexer-cjs.js index a34c1a583..ce1fd644c 100644 --- a/packages/jison-lex/dist/regexp-lexer-cjs.js +++ b/packages/jison-lex/dist/regexp-lexer-cjs.js @@ -7,7 +7,7 @@ var json5 = _interopDefault(require('@gerhobbelt/json5')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -163,6 +163,16 @@ function dquote(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -269,6 +279,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -313,13 +324,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -398,15 +409,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -434,10 +455,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -980,7 +998,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1030,7 +1049,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1188,104 +1207,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, - -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + EOF: 1, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4252,14 +4274,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4365,8 +4387,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4984,7 +5005,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4994,13 +5014,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5640,13 +5663,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5659,7 +5681,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7289,7 +7311,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -8937,7 +8958,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -8951,7 +8972,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -8960,7 +8981,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9149,7 +9170,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9418,9 +9439,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9573,8 +9594,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9589,7 +9610,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9712,6 +9733,14 @@ var version = '0.6.1-215'; // require('./package.js +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -9903,7 +9932,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -9911,7 +9940,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -9992,6 +10021,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10138,7 +10168,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10195,7 +10225,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10250,7 +10280,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10296,7 +10326,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10387,7 +10417,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10424,7 +10454,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10492,7 +10522,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10539,7 +10569,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10752,7 +10782,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -10781,9 +10811,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -10850,11 +10882,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -10865,7 +10897,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -10875,7 +10907,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -10888,8 +10920,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -10900,8 +10932,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12211,6 +12243,7 @@ return `{ // --- END lexer kernel --- } +chkBugger(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS` return ${getRegExpLexerPrototype()}; `))(); @@ -12322,6 +12355,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12480,6 +12514,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12552,9 +12587,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12598,8 +12633,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/regexp-lexer-es6.js b/packages/jison-lex/dist/regexp-lexer-es6.js index 793449ea5..e9d9f9b3a 100644 --- a/packages/jison-lex/dist/regexp-lexer-es6.js +++ b/packages/jison-lex/dist/regexp-lexer-es6.js @@ -3,7 +3,7 @@ import json5 from '@gerhobbelt/json5'; import fs from 'fs'; import path from 'path'; import recast from '@gerhobbelt/recast'; -import assert from 'assert'; +import assert$1 from 'assert'; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -159,6 +159,16 @@ function dquote(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -265,6 +275,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -309,13 +320,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -394,15 +405,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -430,10 +451,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -976,7 +994,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1026,7 +1045,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1184,104 +1203,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, - -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + EOF: 1, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4248,14 +4270,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4361,8 +4383,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4980,7 +5001,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4990,13 +5010,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5636,13 +5659,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5655,7 +5677,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7285,7 +7307,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -8933,7 +8954,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -8947,7 +8968,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -8956,7 +8977,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9145,7 +9166,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9414,9 +9435,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9569,8 +9590,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9585,7 +9606,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9708,6 +9729,14 @@ var version = '0.6.1-215'; // require('./package.js +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -9899,7 +9928,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -9907,7 +9936,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -9988,6 +10017,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10134,7 +10164,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10191,7 +10221,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10246,7 +10276,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10292,7 +10322,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10383,7 +10413,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10420,7 +10450,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10488,7 +10518,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10535,7 +10565,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10748,7 +10778,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -10777,9 +10807,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -10846,11 +10878,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -10861,7 +10893,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -10871,7 +10903,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -10884,8 +10916,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -10896,8 +10928,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12207,6 +12239,7 @@ return `{ // --- END lexer kernel --- } +chkBugger(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS` return ${getRegExpLexerPrototype()}; `))(); @@ -12318,6 +12351,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12476,6 +12510,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12548,9 +12583,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12594,8 +12629,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/regexp-lexer-umd-es5.js b/packages/jison-lex/dist/regexp-lexer-umd-es5.js index 0487fffc9..becca7ad6 100644 --- a/packages/jison-lex/dist/regexp-lexer-umd-es5.js +++ b/packages/jison-lex/dist/regexp-lexer-umd-es5.js @@ -48,8 +48,8 @@ var _templateObject = _taggedTemplateLiteral(['\n There\'s an error in yo function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } (function (global, factory) { - (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', '@gerhobbelt/json5', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : global['regexp-lexer'] = factory(global.XRegExp, global.json5, global.fs, global.path, global.recast, global.assert); -})(undefined, function (XRegExp, json5, fs, path, recast, assert) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', '@gerhobbelt/json5', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : global['regexp-lexer'] = factory(global.XRegExp, global.json5, global.fs, global.path, global.recast, global.assert$1); +})(undefined, function (XRegExp, json5, fs, path, recast, assert$1) { 'use strict'; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; @@ -57,7 +57,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; - assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; + assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -209,6 +209,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -299,6 +306,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -338,13 +346,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi //import astUtils from '@gerhobbelt/ast-util'; - assert(recast); + assert$1(recast); var types = recast.types; - assert(types); + assert$1(types); var namedTypes = types.namedTypes; - assert(namedTypes); + assert$1(namedTypes); var b = types.builders; - assert(b); + assert$1(b); // //assert(astUtils); @@ -408,15 +416,24 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi checkActionBlock: checkActionBlock$1 }; + function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -442,10 +459,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; - // hack: - var assert$1; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -971,7 +985,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2560,14 +2575,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2656,8 +2671,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3212,14 +3226,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -3715,13 +3730,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -3734,7 +3749,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5333,7 +5348,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -6649,7 +6663,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -6663,7 +6677,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -6672,7 +6686,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -6856,7 +6870,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -7122,9 +7136,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -7274,8 +7288,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -7290,7 +7304,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -7404,6 +7418,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var version = '0.6.1-215'; // require('./package.json').version; + function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` var CHR_RE = setmgmt.CHR_RE; var SET_PART_RE = setmgmt.SET_PART_RE; @@ -7589,7 +7610,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -7597,7 +7618,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -7678,6 +7699,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -7818,7 +7840,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -7875,7 +7897,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -7930,7 +7952,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -7975,7 +7997,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -8066,7 +8088,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -8103,7 +8125,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -8168,7 +8190,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -8215,7 +8237,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -8348,7 +8370,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -8372,6 +8394,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); var lexer = code_exec(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -8438,11 +8461,11 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -8453,14 +8476,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.'; }, ex, null)) { var rulesSpecSize; if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -8473,8 +8496,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -8485,8 +8508,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -8579,6 +8602,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // --- END lexer kernel --- } + chkBugger(getRegExpLexerPrototype()); RegExpLexer.prototype = new Function(rmCommonWS(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and @@ -8642,6 +8666,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -8800,6 +8825,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -8866,9 +8892,9 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi protosrc = protosrc.replace(/^[\s\r\n]*\{/, '').replace(/\s*\}[\s\r\n]*$/, '').trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -8903,8 +8929,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/jison-lex/dist/regexp-lexer-umd.js b/packages/jison-lex/dist/regexp-lexer-umd.js index 846fadb2d..35959a2b9 100644 --- a/packages/jison-lex/dist/regexp-lexer-umd.js +++ b/packages/jison-lex/dist/regexp-lexer-umd.js @@ -1,15 +1,15 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('@gerhobbelt/json5'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', '@gerhobbelt/json5', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : - (global['regexp-lexer'] = factory(global.XRegExp,global.json5,global.fs,global.path,global.recast,global.assert)); -}(this, (function (XRegExp,json5,fs,path,recast,assert) { 'use strict'; + (global['regexp-lexer'] = factory(global.XRegExp,global.json5,global.fs,global.path,global.recast,global.assert$1)); +}(this, (function (XRegExp,json5,fs,path,recast,assert$1) { 'use strict'; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; json5 = json5 && json5.hasOwnProperty('default') ? json5['default'] : json5; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; -assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; +assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -165,6 +165,16 @@ function dquote(s) { // +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -271,6 +281,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger$1(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -315,13 +326,13 @@ var code_exec$1 = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -400,15 +411,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$2(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$2(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$2(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -436,10 +457,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -982,7 +1000,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1032,7 +1051,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1190,104 +1209,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, - -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + EOF: 1, -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. - // - // An example of this may be where a rule's action code contains a call like this: + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. // - // parser.getSymbolName(#$) - // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; } - } - return null; -}, -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. + // + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. + // + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. + // + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; + } + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4254,14 +4276,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4367,8 +4389,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4986,7 +5007,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4996,13 +5016,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5642,13 +5665,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5661,7 +5683,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7291,7 +7313,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, @@ -8939,7 +8960,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { for (i = 0; i <= UNICODE_BASE_PLANE_MAX_CP$1; i++) { k = t[i][0]; if (t[i].length === 1 && !done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); lut.push([i, k]); done[k] = true; } @@ -8953,7 +8974,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { } if (!done[k]) { - assert(l[k] > 0); + assert$1(l[k] > 0); // find a minimum span character to mark this one: var w = Infinity; var rv; @@ -8962,7 +8983,7 @@ function updatePcodesBitarrayCacheTestOrder(opts) { if (ba[i]) { var tl = t[i].length; if (tl > 1 && tl < w) { - assert(l[k] > 0); + assert$1(l[k] > 0); rv = [i, k]; w = tl; } @@ -9151,7 +9172,7 @@ function set2bitarray(bitarr, s, opts) { s = s.substr(c1.length); // check for \S, \s, \D, \d, \W, \w and expand them: var ba4e = EscCode_bitarray_output_refs.esc2bitarr[c1[1]]; - assert(ba4e); + assert$1(ba4e); add2bitarray(bitarr, ba4e); continue; @@ -9420,9 +9441,9 @@ function bitarray2set(l, output_inverted_variant, output_minimized) { } } - assert(rv.length); + assert$1(rv.length); var s = rv.join(''); - assert(s); + assert$1(s); // Check if the set is better represented by one of the regex escapes: var esc4s = EscCode_bitarray_output_refs.set2esc[s]; @@ -9575,8 +9596,8 @@ function reduceRegexToSetBitArray(s, name, opts) { // inside a regex set: try { var re; - assert(s); - assert(!(s instanceof Error)); + assert$1(s); + assert$1(!(s instanceof Error)); re = new XRegExp('[' + s + ']'); re.test(s[0]); @@ -9591,7 +9612,7 @@ function reduceRegexToSetBitArray(s, name, opts) { s = new Error('[macro [' + name + '] is unsuitable for use inside regex set expressions: "[' + s + ']"]: ' + ex.message); } - assert(s); + assert$1(s); // propagate deferred exceptions = error reports. if (s instanceof Error) { return s; @@ -9714,6 +9735,14 @@ var version = '0.6.1-215'; // require('./package.js +function chkBugger(src) { + src = '' + src; + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + const XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` const CHR_RE = setmgmt.CHR_RE; @@ -9905,7 +9934,7 @@ function autodetectAndConvertToJSONformat(lexerSpec, options) { function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) { var m, i, k, rule, action, conditions; var active_conditions; - assert(Array.isArray(dict.rules)); + assert$1(Array.isArray(dict.rules)); var rules = dict.rules.slice(0); // shallow copy of the rules array as we MAY modify it in here! var newRules = []; var macros = {}; @@ -9913,7 +9942,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) var simple_rule_count = 0; // Assure all options are camelCased: - assert(typeof opts.options['case-insensitive'] === 'undefined'); + assert$1(typeof opts.options['case-insensitive'] === 'undefined'); if (!tokens) { tokens = {}; @@ -9994,6 +10023,7 @@ function prepareRules(dict, actions, caseHelper, tokens, startConditions, opts) // Also cope with Arrow Functions (and inline those as well?). // See also https://github.com/zaach/jison-lex/issues/23 action = String(action); + chkBugger(action); if (action.match(/^\s*function\s*\(\)\s*\{/)) { action = action.replace(/^\s*function\s*\(\)\s*\{/, '').replace(/\}\s*$/, ''); } else if (action.match(/^\s*\(\)\s*=>[\s\r\n]*[^\s\r\n\{]/)) { @@ -10140,7 +10170,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse // expand any macros in here: if (expandAllMacrosInSet_cb) { se = expandAllMacrosInSet_cb(se); - assert(se); + assert$1(se); if (se instanceof Error) { return new Error(errinfo() + ': ' + se.message); } @@ -10197,7 +10227,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse c2 = c1 + c2 + c3; if (expandAllMacrosElsewhere_cb) { c2 = expandAllMacrosElsewhere_cb(c2); - assert(c2); + assert$1(c2); if (c2 instanceof Error) { return new Error(errinfo() + ': ' + c2.message); } @@ -10252,7 +10282,7 @@ function reduceRegex(s, name, opts, expandAllMacrosInSet_cb, expandAllMacrosElse return new Error(errinfo() + ': expands to an invalid regex: /' + s + '/'); } - assert(s); + assert$1(s); return s; } @@ -10298,7 +10328,7 @@ function prepareMacros(dict_macros, opts) { a = m.split('{' + k + '}'); if (a.length > 1) { var x = expandMacroInSet(k); - assert(x); + assert$1(x); if (x instanceof Error) { m = x; break; @@ -10389,7 +10419,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroInSet(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in set [' + s + ']: ' + x.message); } @@ -10426,7 +10456,7 @@ function prepareMacros(dict_macros, opts) { var a = s.split('{' + i + '}'); if (a.length > 1) { x = expandMacroElsewhere(i); - assert(x); + assert$1(x); if (x instanceof Error) { return new Error('failure to expand the macro [' + i + '] in regex /' + s + '/: ' + x.message); } @@ -10494,7 +10524,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { x = m.in_set; - assert(x); + assert$1(x); if (x instanceof Error) { // this turns out to be an macro with 'issues' and it is used, so the 'issues' do matter: bombs away! throw x; @@ -10541,7 +10571,7 @@ function expandMacros(src, macros, opts) { if (a.length > 1) { // These are all main macro expansions, hence CAPTURING grouping is applied: x = m.elsewhere; - assert(x); + assert$1(x); // detect definition loop: if (x === false) { @@ -10754,7 +10784,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts = processGrammar(dict, tokens, build_options); opts.__in_rules_failure_analysis_mode__ = false; prepExportStructures(opts); - assert(opts.options); + assert$1(opts.options); if (tweak_cb) { tweak_cb(); } @@ -10783,9 +10813,11 @@ function RegExpLexer(dict, input, tokens, build_options) { '', source, '', - 'return lexer;'].join('\n'); + 'return lexer;' + ].join('\n'); var lexer = code_exec(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); + chkBugger(sourcecode); var lexer_f = new Function('', sourcecode); return lexer_f(); }, opts.options, "lexer"); @@ -10852,11 +10884,11 @@ function RegExpLexer(dict, input, tokens, build_options) { // When we get an exception here, it means some part of the user-specified lexer is botched. // // Now we go and try to narrow down the problem area/category: - assert(opts.options); - assert(opts.options.xregexp !== undefined); + assert$1(opts.options); + assert$1(opts.options.xregexp !== undefined); var orig_xregexp_opt = !!opts.options.xregexp; if (!test_me(function () { - assert(opts.options.xregexp !== undefined); + assert$1(opts.options.xregexp !== undefined); opts.options.xregexp = false; opts.showSource = false; }, 'When you have specified %option xregexp, you must also properly IMPORT the XRegExp library in the generated lexer.', ex, null)) { @@ -10867,7 +10899,7 @@ function RegExpLexer(dict, input, tokens, build_options) { opts.conditions = []; opts.showSource = false; }, function () { - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); return (opts.rules.length > 0 ? 'One or more of your lexer state names are possibly botched?' : 'Your custom lexer is somehow botched.' @@ -10877,7 +10909,7 @@ function RegExpLexer(dict, input, tokens, build_options) { if (!test_me(function () { // store the parsed rule set size so we can use that info in case // this attempt also fails: - assert(Array.isArray(opts.rules)); + assert$1(Array.isArray(opts.rules)); rulesSpecSize = opts.rules.length; // opts.conditions = []; @@ -10890,8 +10922,8 @@ function RegExpLexer(dict, input, tokens, build_options) { for (var i = 0, len = rulesSpecSize; i < len; i++) { var lastEditedRuleSpec; rv = test_me(function () { - assert(Array.isArray(opts.rules)); - assert(opts.rules.length === rulesSpecSize); + assert$1(Array.isArray(opts.rules)); + assert$1(opts.rules.length === rulesSpecSize); // opts.conditions = []; // opts.rules = []; @@ -10902,8 +10934,8 @@ function RegExpLexer(dict, input, tokens, build_options) { // rules, when parsed, have 2 or 3 elements: [conditions, handle, action]; // now we want to edit the *action* part: var rule = opts.rules[j]; - assert(Array.isArray(rule)); - assert(rule.length === 2 || rule.length === 3); + assert$1(Array.isArray(rule)); + assert$1(rule.length === 2 || rule.length === 3); rule.pop(); rule.push('{ /* nada */ }'); lastEditedRuleSpec = rule; @@ -12213,6 +12245,7 @@ return `{ // --- END lexer kernel --- } +chkBugger(getRegExpLexerPrototype()); RegExpLexer.prototype = (new Function(rmCommonWS` return ${getRegExpLexerPrototype()}; `))(); @@ -12324,6 +12357,7 @@ function processGrammar(dict, tokens, build_options) { parseActionsUseYYSSTACK: build_options.parseActionsUseYYSSTACK, parseActionsUseYYSTACKPOINTER: build_options.parseActionsUseYYSTACKPOINTER, parseActionsUseYYRULELENGTH: build_options.parseActionsUseYYRULELENGTH, + parseActionsUseYYMERGELOCATIONINFO: build_options.parseActionsUseYYMERGELOCATIONINFO, parserHasErrorRecovery: build_options.parserHasErrorRecovery, parserHasErrorReporting: build_options.parserHasErrorReporting, @@ -12482,6 +12516,7 @@ function generateModuleBody(opt) { parseActionsUseYYSSTACK: 1, parseActionsUseYYSTACKPOINTER: 1, parseActionsUseYYRULELENGTH: 1, + parseActionsUseYYMERGELOCATIONINFO: 1, parserHasErrorRecovery: 1, parserHasErrorReporting: 1, lexerActionsUseYYLENG: 1, @@ -12554,9 +12589,9 @@ function generateModuleBody(opt) { .trim(); code.push(protosrc + ',\n'); - assert(opt.options); + assert$1(opt.options); // Assure all options are camelCased: - assert(typeof opt.options['case-insensitive'] === 'undefined'); + assert$1(typeof opt.options['case-insensitive'] === 'undefined'); code.push(' options: ' + produceOptions(opt.options)); @@ -12600,8 +12635,8 @@ function generateModuleBody(opt) { // what crazy stuff (or lack thereof) the userland code is pulling in the `actionInclude` chunk. out = 'var lexer;\n'; - assert(opt.regular_rule_count === 0); - assert(opt.simple_rule_count === 0); + assert$1(opt.regular_rule_count === 0); + assert$1(opt.simple_rule_count === 0); opt.is_custom_lexer = true; if (opt.actionInclude) { diff --git a/packages/lex-parser/dist/lex-parser-cjs-es5.js b/packages/lex-parser/dist/lex-parser-cjs-es5.js index 2a89fa866..cec33b883 100644 --- a/packages/lex-parser/dist/lex-parser-cjs-es5.js +++ b/packages/lex-parser/dist/lex-parser-cjs-es5.js @@ -48,7 +48,7 @@ var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -200,6 +200,13 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -290,6 +297,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -329,13 +337,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -399,15 +407,24 @@ var parse2AST = { checkActionBlock: checkActionBlock$1 }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -433,10 +450,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -962,7 +976,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2551,14 +2566,14 @@ var parser = { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2647,8 +2662,7 @@ var parser = { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3203,14 +3217,15 @@ var parser = { recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -3706,13 +3721,13 @@ var parser = { throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -3725,7 +3740,7 @@ var parser = { }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5324,7 +5339,6 @@ var lexer = function () { xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/lex-parser/dist/lex-parser-cjs.js b/packages/lex-parser/dist/lex-parser-cjs.js index d802aabc8..837c94498 100644 --- a/packages/lex-parser/dist/lex-parser-cjs.js +++ b/packages/lex-parser/dist/lex-parser-cjs.js @@ -6,7 +6,7 @@ var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); -var assert = _interopDefault(require('assert')); +var assert$1 = _interopDefault(require('assert')); // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -162,6 +162,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -268,6 +278,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -312,13 +323,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -397,15 +408,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -433,10 +454,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -979,7 +997,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1029,7 +1048,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1187,104 +1206,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4251,14 +4273,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4364,8 +4386,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4983,7 +5004,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4993,13 +5013,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5639,13 +5662,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5658,7 +5680,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7288,7 +7310,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/lex-parser/dist/lex-parser-es6.js b/packages/lex-parser/dist/lex-parser-es6.js index 42b7c35ea..61cbef2fa 100644 --- a/packages/lex-parser/dist/lex-parser-es6.js +++ b/packages/lex-parser/dist/lex-parser-es6.js @@ -2,7 +2,7 @@ import XRegExp from '@gerhobbelt/xregexp'; import fs from 'fs'; import path from 'path'; import recast from '@gerhobbelt/recast'; -import assert from 'assert'; +import assert$1 from 'assert'; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -158,6 +158,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -264,6 +274,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -308,13 +319,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -393,15 +404,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -429,10 +450,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -975,7 +993,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1025,7 +1044,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1183,104 +1202,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4247,14 +4269,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4360,8 +4382,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4979,7 +5000,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4989,13 +5009,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5635,13 +5658,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5654,7 +5676,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7284,7 +7306,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/lex-parser/dist/lex-parser-umd-es5.js b/packages/lex-parser/dist/lex-parser-umd-es5.js index 7800de61c..197c1094f 100644 --- a/packages/lex-parser/dist/lex-parser-umd-es5.js +++ b/packages/lex-parser/dist/lex-parser-umd-es5.js @@ -41,15 +41,15 @@ var _templateObject = _taggedTemplateLiteral(['\n There\'s an error in yo function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } (function (global, factory) { - (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : global['lex-parser'] = factory(global.XRegExp, global.fs, global.path, global.recast, global.assert); -})(undefined, function (XRegExp, fs, path, recast, assert) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : global['lex-parser'] = factory(global.XRegExp, global.fs, global.path, global.recast, global.assert$1); +})(undefined, function (XRegExp, fs, path, recast, assert$1) { 'use strict'; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; - assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; + assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -201,6 +201,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // + function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -291,6 +298,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -330,13 +338,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi //import astUtils from '@gerhobbelt/ast-util'; - assert(recast); + assert$1(recast); var types = recast.types; - assert(types); + assert$1(types); var namedTypes = types.namedTypes; - assert(namedTypes); + assert$1(namedTypes); var b = types.builders; - assert(b); + assert$1(b); // //assert(astUtils); @@ -400,15 +408,24 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi checkActionBlock: checkActionBlock$1 }; + function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } + } + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -434,10 +451,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; - // hack: - var assert$1; - - /* parser generated by jison 0.6.1-214 */ + /* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -963,7 +977,8 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -2552,14 +2567,14 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -2648,8 +2663,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -3204,14 +3218,15 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi recoveringErrorInfo = this.shallowCopyErrorInfo(p); r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -3707,13 +3722,13 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi throw ex; } else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; - } else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -3726,7 +3741,7 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; - /* lexer generated by jison-lex 0.6.1-214 */ + /* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -5325,7 +5340,6 @@ function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defi xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/lex-parser/dist/lex-parser-umd.js b/packages/lex-parser/dist/lex-parser-umd.js index f1e8f7cc5..994b2decb 100644 --- a/packages/lex-parser/dist/lex-parser-umd.js +++ b/packages/lex-parser/dist/lex-parser-umd.js @@ -1,14 +1,14 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@gerhobbelt/xregexp'), require('fs'), require('path'), require('@gerhobbelt/recast'), require('assert')) : typeof define === 'function' && define.amd ? define(['@gerhobbelt/xregexp', 'fs', 'path', '@gerhobbelt/recast', 'assert'], factory) : - (global['lex-parser'] = factory(global.XRegExp,global.fs,global.path,global.recast,global.assert)); -}(this, (function (XRegExp,fs,path,recast,assert) { 'use strict'; + (global['lex-parser'] = factory(global.XRegExp,global.fs,global.path,global.recast,global.assert$1)); +}(this, (function (XRegExp,fs,path,recast,assert$1) { 'use strict'; XRegExp = XRegExp && XRegExp.hasOwnProperty('default') ? XRegExp['default'] : XRegExp; fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs; path = path && path.hasOwnProperty('default') ? path['default'] : path; recast = recast && recast.hasOwnProperty('default') ? recast['default'] : recast; -assert = assert && assert.hasOwnProperty('default') ? assert['default'] : assert; +assert$1 = assert$1 && assert$1.hasOwnProperty('default') ? assert$1['default'] : assert$1; // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { @@ -164,6 +164,16 @@ function dquote(s) { // +function chkBugger(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + + + // Helper function: pad number with leading zeroes function pad(n, p) { p = p || 2; @@ -270,6 +280,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t if (typeof code_execution_rig !== 'function') { throw new Error("safe-code-exec-and-diag: code_execution_rig MUST be a JavaScript function"); } + chkBugger(sourcecode); p = code_execution_rig.call(this, sourcecode, options, errname, debug); } catch (ex) { if (debug > 1) console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); @@ -314,13 +325,13 @@ var code_exec = { //import astUtils from '@gerhobbelt/ast-util'; -assert(recast); +assert$1(recast); var types = recast.types; -assert(types); +assert$1(types); var namedTypes = types.namedTypes; -assert(namedTypes); +assert$1(namedTypes); var b = types.builders; -assert(b); +assert$1(b); // //assert(astUtils); @@ -399,15 +410,25 @@ var parse2AST = { checkActionBlock: checkActionBlock$1, }; +function chkBugger$1(src) { + src = String(src); + if (src.match(/\bcov_\w+/)) { + console.error('### ISTANBUL COVERAGE CODE DETECTED ###\n', src); + } +} + + /// HELPER FUNCTION: print the function in source code form, properly indented. /** @public */ function printFunctionSourceCode(f) { + chkBugger$1(f); return String(f); } /// HELPER FUNCTION: print the function **content** in source code form, properly indented. /** @public */ function printFunctionSourceCodeContainer(f) { + chkBugger$1(f); return String(f).replace(/^[\s\r\n]*function\b[^\{]+\{/, '').replace(/\}[\s\r\n]*$/, ''); } @@ -435,10 +456,7 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer, }; -// hack: -var assert$1; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -981,7 +999,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -1031,7 +1050,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -1189,104 +1208,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -4253,14 +4275,14 @@ parse: function parse(input) { }; var ASSERT; - if (typeof assert$1 !== 'function') { + if (typeof assert !== 'function') { ASSERT = function JisonAssert(cond, msg) { if (!cond) { throw new Error('assertion failed: ' + (msg || '***')); } }; } else { - ASSERT = assert$1; + ASSERT = assert; } this.yyGetSharedState = function yyGetSharedState() { @@ -4366,8 +4388,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4985,7 +5006,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4995,13 +5015,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5641,13 +5664,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5660,7 +5682,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -7290,7 +7312,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/packages/lex-parser/lex-parser.js b/packages/lex-parser/lex-parser.js index 15fdc1915..4196247d9 100644 --- a/packages/lex-parser/lex-parser.js +++ b/packages/lex-parser/lex-parser.js @@ -1,8 +1,5 @@ -// hack: -var assert; - -/* parser generated by jison 0.6.1-214 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -549,7 +546,8 @@ var parser = { // // Options: // - // default action mode: ............. classic,merge + // default action mode: ............. ["classic","merge"] + // test-compile action mode: ........ "parser:*,lexer:*" // try..catch: ...................... true // default resolve on conflict: ..... true // on-demand look-ahead: ............ false @@ -599,7 +597,7 @@ var parser = { // // --------- END OF REPORT ----------- -trace: function no_op_trace() {}, +trace: function no_op_trace() { }, JisonParserError: JisonParserError, yy: {}, options: { @@ -757,104 +755,107 @@ terminals_: { 53: "CODE" }, TERROR: 2, -EOF: 1, + EOF: 1, + + // internals: defined here so the object *structure* doesn't get modified by parse() et al, + // thus helping JIT compilers like Chrome V8. + originalQuoteName: null, + originalParseError: null, + cleanupAfterParse: null, + constructParseErrorInfo: null, + yyMergeLocationInfo: null, + + __reentrant_call_depth: 0, // INTERNAL USE ONLY + __error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + __error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup + + // APIs which will be set up depending on user action code analysis: + //yyRecovering: 0, + //yyErrOk: 0, + //yyClearIn: 0, + + // Helper APIs + // ----------- + + // Helper function which can be overridden by user code later on: put suitable quotes around + // literal IDs in a description string. + quoteName: function parser_quoteName(id_str) { + return '"' + id_str + '"'; + }, -// internals: defined here so the object *structure* doesn't get modified by parse() et al, -// thus helping JIT compilers like Chrome V8. -originalQuoteName: null, -originalParseError: null, -cleanupAfterParse: null, -constructParseErrorInfo: null, -yyMergeLocationInfo: null, - -__reentrant_call_depth: 0, // INTERNAL USE ONLY -__error_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup -__error_recovery_infos: [], // INTERNAL USE ONLY: the set of parseErrorInfo objects created since the last cleanup - -// APIs which will be set up depending on user action code analysis: -//yyRecovering: 0, -//yyErrOk: 0, -//yyClearIn: 0, - -// Helper APIs -// ----------- - -// Helper function which can be overridden by user code later on: put suitable quotes around -// literal IDs in a description string. -quoteName: function parser_quoteName(id_str) { - return '"' + id_str + '"'; -}, + // Return the name of the given symbol (terminal or non-terminal) as a string, when available. + // + // Return NULL when the symbol is unknown to the parser. + getSymbolName: function parser_getSymbolName(symbol) { + if (this.terminals_[symbol]) { + return this.terminals_[symbol]; + } -// Return the name of the given symbol (terminal or non-terminal) as a string, when available. -// -// Return NULL when the symbol is unknown to the parser. -getSymbolName: function parser_getSymbolName(symbol) { - if (this.terminals_[symbol]) { - return this.terminals_[symbol]; - } + // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // + // An example of this may be where a rule's action code contains a call like this: + // + // parser.getSymbolName(#$) + // + // to obtain a human-readable name of the current grammar rule. + var s = this.symbols_; + for (var key in s) { + if (s[key] === symbol) { + return key; + } + } + return null; + }, - // Otherwise... this might refer to a RULE token i.e. a non-terminal: see if we can dig that one up. + // Return a more-or-less human-readable description of the given symbol, when available, + // or the symbol itself, serving as its own 'description' for lack of something better to serve up. // - // An example of this may be where a rule's action code contains a call like this: + // Return NULL when the symbol is unknown to the parser. + describeSymbol: function parser_describeSymbol(symbol) { + if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { + return this.terminal_descriptions_[symbol]; + } + else if (symbol === this.EOF) { + return 'end of input'; + } + var id = this.getSymbolName(symbol); + if (id) { + return this.quoteName(id); + } + return null; + }, + + // Produce a (more or less) human-readable list of expected tokens at the point of failure. // - // parser.getSymbolName(#$) + // The produced list may contain token or token set descriptions instead of the tokens + // themselves to help turning this output into something that easier to read by humans + // unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, + // expected terminals and nonterminals is produced. // - // to obtain a human-readable name of the current grammar rule. - var s = this.symbols_; - for (var key in s) { - if (s[key] === symbol) { - return key; + // The returned list (array) will not contain any duplicate entries. + collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { + var TERROR = this.TERROR; + var tokenset = []; + var check = {}; + // Has this (error?) state been outfitted with a custom expectations description text for human consumption? + // If so, use that one instead of the less palatable token set. + if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { + return [ + this.state_descriptions_[state] + ]; } - } - return null; -}, - -// Return a more-or-less human-readable description of the given symbol, when available, -// or the symbol itself, serving as its own 'description' for lack of something better to serve up. -// -// Return NULL when the symbol is unknown to the parser. -describeSymbol: function parser_describeSymbol(symbol) { - if (symbol !== this.EOF && this.terminal_descriptions_ && this.terminal_descriptions_[symbol]) { - return this.terminal_descriptions_[symbol]; - } else if (symbol === this.EOF) { - return 'end of input'; - } - var id = this.getSymbolName(symbol); - if (id) { - return this.quoteName(id); - } - return null; -}, - -// Produce a (more or less) human-readable list of expected tokens at the point of failure. -// -// The produced list may contain token or token set descriptions instead of the tokens -// themselves to help turning this output into something that easier to read by humans -// unless `do_not_describe` parameter is set, in which case a list of the raw, *numeric*, -// expected terminals and nonterminals is produced. -// -// The returned list (array) will not contain any duplicate entries. -collect_expected_token_set: function parser_collect_expected_token_set(state, do_not_describe) { - var TERROR = this.TERROR; - var tokenset = []; - var check = {}; - // Has this (error?) state been outfitted with a custom expectations description text for human consumption? - // If so, use that one instead of the less palatable token set. - if (!do_not_describe && this.state_descriptions_ && this.state_descriptions_[state]) { - return [this.state_descriptions_[state]]; - } - for (var p in this.table[state]) { - p = +p; - if (p !== TERROR) { - var d = do_not_describe ? p : this.describeSymbol(p); - if (d && !check[d]) { - tokenset.push(d); - check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + for (var p in this.table[state]) { + p = +p; + if (p !== TERROR) { + var d = do_not_describe ? p : this.describeSymbol(p); + if (d && !check[d]) { + tokenset.push(d); + check[d] = true; // Mark this token description as already mentioned to prevent outputting duplicate entries. + } } } - } - return tokenset; -}, + return tokenset; + }, productions_: bp({ pop: u([ 54, @@ -3934,8 +3935,7 @@ parse: function parse(input) { hash.extra_error_attributes = args; } - var r = this.parseError(str, hash, this.JisonParserError); - return r; + return this.parseError(str, hash, this.JisonParserError); }; } @@ -4562,7 +4562,6 @@ parse: function parse(input) { // invoke the parser's cleanup API! recoveringErrorInfo = this.shallowCopyErrorInfo(p); - r = this.parseError(p.errStr, p, this.JisonParserError); @@ -4572,13 +4571,16 @@ parse: function parse(input) { + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; + break; + } + // Protect against overly blunt userland `parseError` code which *sets* // the `recoverable` flag without properly checking first: // we always terminate the parse when there's no recovery rule available anyhow! if (!p.recoverable || error_rule_depth < 0) { - if (typeof r !== 'undefined') { - retval = r; - } break; } else { // TODO: allow parseError callback to edit symbol and or state at the start of the error recovery process... @@ -5218,13 +5220,12 @@ parse: function parse(input) { else if (lexer && typeof lexer.JisonLexerError === 'function' && ex instanceof lexer.JisonLexerError) { throw ex; } - else { - p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); - retval = false; - r = this.parseError(p.errStr, p, this.JisonParserError); - if (typeof r !== 'undefined') { - retval = r; - } + + p = this.constructParseErrorInfo('Parsing aborted due to exception.', ex, null, false); + retval = false; + r = this.parseError(p.errStr, p, this.JisonParserError); + if (typeof r !== 'undefined') { + retval = r; } } finally { retval = this.cleanupAfterParse(retval, true, true); @@ -5237,7 +5238,7 @@ yyError: 1 }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-214 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -6867,7 +6868,6 @@ EOF: 1, xregexp: true, ranges: true, trackPosition: true, - parseActionsUseYYMERGELOCATIONINFO: true, easy_keyword_rules: true }, diff --git a/web/content/assets/js/calculator.js b/web/content/assets/js/calculator.js index a13303c33..64b179c1c 100644 --- a/web/content/assets/js/calculator.js +++ b/web/content/assets/js/calculator.js @@ -1,5 +1,5 @@ -/* parser generated by jison 0.6.1-213 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1697,7 +1697,7 @@ parse: function parse(input) { }; parser.originalParseError = parser.parseError; parser.originalQuoteName = parser.quoteName; -/* lexer generated by jison-lex 0.6.1-213 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: diff --git a/web/content/assets/js/jison.js b/web/content/assets/js/jison.js index 6170c726a..f5e321324 100644 --- a/web/content/assets/js/jison.js +++ b/web/content/assets/js/jison.js @@ -112,265 +112,14 @@ function _interopDefault(ex) { return ex && (typeof ex === 'undefined' ? 'undefined' : _typeof(ex)) === 'object' && 'default' in ex ? ex['default'] : ex; } -var assert = _interopDefault(require('assert')); -var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); -var json5 = _interopDefault(require('@gerhobbelt/json5')); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); var recast = _interopDefault(require('@gerhobbelt/recast')); +var assert = _interopDefault(require('assert')); +var XRegExp = _interopDefault(require('@gerhobbelt/xregexp')); +var json5 = _interopDefault(require('@gerhobbelt/json5')); var astUtils = _interopDefault(require('@gerhobbelt/ast-util')); -/* - * Introduces a typal object to make classical/prototypal patterns easier - * Plus some AOP sugar - * - * By Zachary Carter - * MIT Licensed - */ - -var create = Object.create || function (o) { - function F() {} - F.prototype = o; - return new F(); -}; -var position = /^(before|after)/; - -// basic method layering -// always returns original method's return value -function layerMethod(pos, key, prop, fun) { - if (pos === 'after') { - return function () { - var ret = prop.apply(this, arguments); - var args = [].slice.call(arguments); - args.splice(0, 0, ret); - fun.apply(this, args); - return ret; - }; - } else if (pos === 'before') { - return function () { - fun.apply(this, arguments); - var ret = prop.apply(this, arguments); - return ret; - }; - } - return fun; -} - -// mixes each argument's own properties into calling object, -// overwriting them or layering them. i.e. an object method 'meth' is -// layered by mixin methods 'beforemeth' or 'aftermeth' -function typal_mix() { - var i, o, k; - for (i = 0; i < arguments.length; i++) { - o = arguments[i]; - if (!o) continue; - if (Object.prototype.hasOwnProperty.call(o, 'constructor')) { - this.constructor = o.constructor; - } - if (Object.prototype.hasOwnProperty.call(o, 'toString')) { - this.toString = o.toString; - } - for (k in o) { - if (Object.prototype.hasOwnProperty.call(o, k)) { - var match = k.match(position); - var key = k.replace(position, ''); - if (match && typeof this[key] === 'function') { - this[key] = layerMethod(match[0], key, this[key], o[k]); - } else { - this[k] = o[k]; - } - } - } - } - return this; -} - -// Same as typal_mix but also camelCases every object member and 'standardizes' the key set of every input -// argument through a caLLback function. -// -// This is useful for processing options with dashes in their key, e.g. `token-stack` --> tokenStack. -function typal_camel_mix(cb) { - var i, o, k; - - // Convert dashed option keys to Camel Case, e.g. `camelCase('camels-have-one-hump')` => `'camelsHaveOneHump'` - function camelCase(s) { - return s.replace(/-\w/g, function (match) { - return match.charAt(1).toUpperCase(); - }); - } - - // Convert first character to lowercase - function lcase0(s) { - return s.replace(/^\w/, function (match) { - return match.toLowerCase(); - }); - } - - for (i = 1; i < arguments.length; i++) { - o = arguments[i]; - if (!o) continue; - if (Object.prototype.hasOwnProperty.call(o, 'constructor')) { - this.constructor = o.constructor; - } - if (Object.prototype.hasOwnProperty.call(o, 'toString')) { - this.toString = o.toString; - } - if (cb) { - o = cb(o); - } - for (k in o) { - if (Object.prototype.hasOwnProperty.call(o, k)) { - var nk = camelCase(k); - var match = k.match(position); - var key = k.replace(position, ''); - // This anticipates before/after members to be camelcased already, e.g. - // 'afterParse()' for layering 'parse()': - var alt_key = lcase0(key); - if (match && typeof this[key] === 'function') { - this[key] = layerMethod(match[0], key, this[key], o[k]); - } else if (match && typeof this[alt_key] === 'function') { - this[alt_key] = layerMethod(match[0], alt_key, this[alt_key], o[k]); - } else { - this[nk] = o[k]; - } - } - } - } - return this; -} - -var typal = { - // extend object with own properties of each argument - mix: typal_mix, - - camelMix: typal_camel_mix, - - // sugar for object begetting and mixing - // - Object.create(typal).mix(etc, etc); - // + typal.beget(etc, etc); - beget: function typal_beget() { - return arguments.length ? typal_mix.apply(create(this), arguments) : create(this); - }, - - // Creates a new Class function based on an object with a constructor method - construct: function typal_construct() { - var o = typal_mix.apply(create(this), arguments); - var constructor = o.constructor; - var Klass = o.constructor = function () { - return constructor.apply(this, arguments); - }; - Klass.prototype = o; - Klass.mix = typal_mix; // allow for easy singleton property extension - return Klass; - }, - - // no op - constructor: function typal_constructor() { - return this; - } -}; - -// Set class to wrap arrays - -var setMixin = { - constructor: function Set_constructor(set, raw) { - this._items = []; - if (set && set.constructor === Array) { - this._items = raw ? set : set.slice(0); - } else if (arguments.length) { - this._items = [].slice.call(arguments, 0); - } - }, - concat: function concat(setB) { - this._items.push.apply(this._items, setB._items || setB); - return this; - }, - eq: function eq(set) { - return this._items.length === set._items.length && this.subset(set) && this.superset(set); - }, - indexOf: function indexOf(item) { - if (item && item.eq) { - for (var k = 0; k < this._items.length; k++) { - if (item.eq(this._items[k])) { - return k; - } - } - return -1; - } - return this._items.indexOf(item); - }, - intersection: function intersection(set) { - return this.filter(function intersection_filter(elm) { - return set.contains(elm); - }); - }, - complement: function complement(set) { - var that = this; - return set.filter(function sub_complement(elm) { - return !that.contains(elm); - }); - }, - subset: function subset(set) { - var cont = true; - for (var i = 0; i < this._items.length && cont; i++) { - cont = cont && set.contains(this._items[i]); - } - return cont; - }, - superset: function superset(set) { - return set.subset(this); - }, - joinSet: function joinSet(set) { - return this.concat(this.complement(set)); - }, - contains: function contains(item) { - return this.indexOf(item) !== -1; - }, - item: function item(v) { - return this._items[v]; - }, - i: function i(v) { - return this._items[v]; - }, - assign: function assign(index, value) { - this._items[index] = value; - return this; - }, - first: function first() { - return this._items[0]; - }, - last: function last() { - return this._items[this._items.length - 1]; - }, - size: function size() { - return this._items.length; - }, - isEmpty: function isEmpty() { - return this._items.length === 0; - }, - copy: function copy() { - return new Set(this._items); - }, - toString: function toString() { - return this._items.toString(); - } -}; - -'push shift unshift forEach some every join sort'.split(' ').forEach(function (e, i) { - setMixin[e] = function () { - return Array.prototype[e].apply(this._items, arguments); - }; - //setMixin[e].name = e; -}); -'filter slice map'.split(' ').forEach(function (e, i) { - setMixin[e] = function () { - return new Set(Array.prototype[e].apply(this._items, arguments), true); - }; - //setMixin[e].name = e; -}); - -var Set = typal.construct(setMixin); - // Return TRUE if `src` starts with `searchString`. function startsWith(src, searchString) { return src.substr(0, searchString.length) === searchString; @@ -388,7 +137,7 @@ function startsWith(src, searchString) { // should also be removed from all subsequent lines in the same template string. // // See also: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals -function rmCommonWS$3(strings) { +function rmCommonWS$1(strings) { // As `strings[]` is an array of strings, each potentially consisting // of multiple lines, followed by one(1) value, we have to split each // individual string into lines to keep that bit of information intact. @@ -463,15 +212,33 @@ function rmCommonWS$3(strings) { // Convert dashed option keys to Camel Case, e.g. `camelCase('camels-have-one-hump')` => `'camelsHaveOneHump'` /** @public */ -function camelCase$2(s) { +function camelCase(s) { // Convert first character to lowercase return s.replace(/^\w/, function (match) { return match.toLowerCase(); }).replace(/-\w/g, function (match) { - return match.charAt(1).toUpperCase(); + var c = match.charAt(1); + var rv = c.toUpperCase(); + // do not mutate 'a-2' to 'a2': + if (c === rv && c.match(/\d/)) { + return match; + } + return rv; }); } +// Convert dashed option keys and other inputs to Camel Cased legal JavaScript identifiers +/** @public */ +function mkIdentifier$2(s) { + s = camelCase('' + s); + // cleanup: replace any non-suitable character series to a single underscore: + return s.replace(/^[^\w_]/, '_') + // do not accept numerics at the leading position, despite those matching regex `\w`: + .replace(/^\d/, '_').replace(/[^\w\d_]+/g, '_') + // and only accept multiple (double, not triple) underscores at start or end of identifier name: + .replace(/^__+/, '#').replace(/__+$/, '#').replace(/_+/g, '_').replace(/#/g, '__'); +} + // properly quote and escape the given input string function dquote$1(s) { var sq = s.indexOf('\'') >= 0; @@ -614,7 +381,7 @@ function exec_and_diagnose_this_stuff(sourcecode, code_execution_rig, options, t return p; } -var code_exec$2 = { +var code_exec$1 = { exec: exec_and_diagnose_this_stuff, dump: dumpSourceToFile }; @@ -676,7 +443,7 @@ function prettyPrintAST(ast, options) { // validate the given JavaScript snippet: does it compile? // // Return either the parsed AST (object) or an error message (string). -function checkActionBlock$1(src, yylloc) { +function checkActionBlock(src, yylloc) { // make sure reasonable line numbers, etc. are reported in any // potential parse errors by pushing the source code down: if (yylloc && yylloc.first_line > 0) { @@ -699,7 +466,7 @@ function checkActionBlock$1(src, yylloc) { var parse2AST = { parseCodeChunkToAST: parseCodeChunkToAST, prettyPrintAST: prettyPrintAST, - checkActionBlock: checkActionBlock$1 + checkActionBlock: checkActionBlock }; /// HELPER FUNCTION: print the function in source code form, properly indented. @@ -720,12 +487,13 @@ var stringifier = { }; var helpers = { - rmCommonWS: rmCommonWS$3, - camelCase: camelCase$2, + rmCommonWS: rmCommonWS$1, + camelCase: camelCase, + mkIdentifier: mkIdentifier$2, dquote: dquote$1, - exec: code_exec$2.exec, - dump: code_exec$2.dump, + exec: code_exec$1.exec, + dump: code_exec$1.dump, parseCodeChunkToAST: parse2AST.parseCodeChunkToAST, prettyPrintAST: parse2AST.prettyPrintAST, @@ -735,10 +503,256 @@ var helpers = { printFunctionSourceCodeContainer: stringifier.printFunctionSourceCodeContainer }; +/* + * Introduces a typal object to make classical/prototypal patterns easier + * Plus some AOP sugar + * + * By Zachary Carter + * MIT Licensed + */ + +var mkIdentifier$1 = helpers.mkIdentifier; + +var create = Object.create || function (o) { + function F() {} + F.prototype = o; + return new F(); +}; +var position = /^(before|after)/; + +// basic method layering +// always returns original method's return value +function layerMethod(pos, key, prop, fun) { + if (pos === 'after') { + return function () { + var ret = prop.apply(this, arguments); + var args = [].slice.call(arguments); + args.splice(0, 0, ret); + fun.apply(this, args); + return ret; + }; + } else if (pos === 'before') { + return function () { + fun.apply(this, arguments); + var ret = prop.apply(this, arguments); + return ret; + }; + } + return fun; +} + +// mixes each argument's own properties into calling object, +// overwriting them or layering them. i.e. an object method 'meth' is +// layered by mixin methods 'beforemeth' or 'aftermeth' +function typal_mix() { + var i, o, k; + for (i = 0; i < arguments.length; i++) { + o = arguments[i]; + if (!o) continue; + if (Object.prototype.hasOwnProperty.call(o, 'constructor')) { + this.constructor = o.constructor; + } + if (Object.prototype.hasOwnProperty.call(o, 'toString')) { + this.toString = o.toString; + } + for (k in o) { + if (Object.prototype.hasOwnProperty.call(o, k)) { + var match = k.match(position); + var key = k.replace(position, ''); + if (match && typeof this[key] === 'function') { + this[key] = layerMethod(match[0], key, this[key], o[k]); + } else { + this[k] = o[k]; + } + } + } + } + return this; +} + +// Same as typal_mix but also camelCases every object member and 'standardizes' the key set of every input +// argument through a caLLback function. +// +// This is useful for processing options with dashes in their key, e.g. `token-stack` --> tokenStack. +function typal_camel_mix(cb) { + var i, o, k; + + // Convert first character to lowercase + function lcase0(s) { + return s.replace(/^\w/, function (match) { + return match.toLowerCase(); + }); + } + + for (i = 1; i < arguments.length; i++) { + o = arguments[i]; + if (!o) continue; + if (Object.prototype.hasOwnProperty.call(o, 'constructor')) { + this.constructor = o.constructor; + } + if (Object.prototype.hasOwnProperty.call(o, 'toString')) { + this.toString = o.toString; + } + if (cb) { + o = cb(o); + } + for (k in o) { + if (Object.prototype.hasOwnProperty.call(o, k)) { + var nk = mkIdentifier$1(k); + var match = k.match(position); + var key = k.replace(position, ''); + // This anticipates before/after members to be camelcased already, e.g. + // 'afterParse()' for layering 'parse()': + var alt_key = lcase0(key); + if (match && typeof this[key] === 'function') { + this[key] = layerMethod(match[0], key, this[key], o[k]); + } else if (match && typeof this[alt_key] === 'function') { + this[alt_key] = layerMethod(match[0], alt_key, this[alt_key], o[k]); + } else { + this[nk] = o[k]; + } + } + } + } + return this; +} + +var typal = { + // extend object with own properties of each argument + mix: typal_mix, + + camelMix: typal_camel_mix, + + // sugar for object begetting and mixing + // - Object.create(typal).mix(etc, etc); + // + typal.beget(etc, etc); + beget: function typal_beget() { + return arguments.length ? typal_mix.apply(create(this), arguments) : create(this); + }, + + // Creates a new Class function based on an object with a constructor method + construct: function typal_construct() { + var o = typal_mix.apply(create(this), arguments); + var constructor = o.constructor; + var Klass = o.constructor = function () { + return constructor.apply(this, arguments); + }; + Klass.prototype = o; + Klass.mix = typal_mix; // allow for easy singleton property extension + return Klass; + }, + + // no op + constructor: function typal_constructor() { + return this; + } +}; + +// Set class to wrap arrays + +var setMixin = { + constructor: function Set_constructor(set, raw) { + this._items = []; + if (set && set.constructor === Array) { + this._items = raw ? set : set.slice(0); + } else if (arguments.length) { + this._items = [].slice.call(arguments, 0); + } + }, + concat: function concat(setB) { + this._items.push.apply(this._items, setB._items || setB); + return this; + }, + eq: function eq(set) { + return this._items.length === set._items.length && this.subset(set) && this.superset(set); + }, + indexOf: function indexOf(item) { + if (item && item.eq) { + for (var k = 0; k < this._items.length; k++) { + if (item.eq(this._items[k])) { + return k; + } + } + return -1; + } + return this._items.indexOf(item); + }, + intersection: function intersection(set) { + return this.filter(function intersection_filter(elm) { + return set.contains(elm); + }); + }, + complement: function complement(set) { + var that = this; + return set.filter(function sub_complement(elm) { + return !that.contains(elm); + }); + }, + subset: function subset(set) { + var cont = true; + for (var i = 0; i < this._items.length && cont; i++) { + cont = cont && set.contains(this._items[i]); + } + return cont; + }, + superset: function superset(set) { + return set.subset(this); + }, + joinSet: function joinSet(set) { + return this.concat(this.complement(set)); + }, + contains: function contains(item) { + return this.indexOf(item) !== -1; + }, + item: function item(v) { + return this._items[v]; + }, + i: function i(v) { + return this._items[v]; + }, + assign: function assign(index, value) { + this._items[index] = value; + return this; + }, + first: function first() { + return this._items[0]; + }, + last: function last() { + return this._items[this._items.length - 1]; + }, + size: function size() { + return this._items.length; + }, + isEmpty: function isEmpty() { + return this._items.length === 0; + }, + copy: function copy() { + return new Set(this._items); + }, + toString: function toString() { + return this._items.toString(); + } +}; + +'push shift unshift forEach some every join sort'.split(' ').forEach(function (e, i) { + setMixin[e] = function () { + return Array.prototype[e].apply(this._items, arguments); + }; + //setMixin[e].name = e; +}); +'filter slice map'.split(' ').forEach(function (e, i) { + setMixin[e] = function () { + return new Set(Array.prototype[e].apply(this._items, arguments), true); + }; + //setMixin[e].name = e; +}); + +var Set = typal.construct(setMixin); + // hack: var assert$1; -/* parser generated by jison 0.6.1-213 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -1635,7 +1649,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 4,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject, yylexer.prettyPrintRange(yylstack[yysp - 1]), yyvstack[yysp - 1].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject, yylexer.prettyPrintRange(yylstack[yysp - 1]), yyvstack[yysp - 1].errStr)); break; case 3: @@ -1662,7 +1676,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 5,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject2, yylexer.prettyPrintRange(yylstack[yysp - 3]), yyvstack[yysp - 3].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject2, yylexer.prettyPrintRange(yylstack[yysp - 3]), yyvstack[yysp - 3].errStr)); break; case 5: @@ -1674,7 +1688,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 4,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject3, yylexer.prettyPrintRange(yylstack[yysp]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject3, yylexer.prettyPrintRange(yylstack[yysp]), yyvstack[yysp].errStr)); break; case 6: @@ -1686,7 +1700,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject2, yylexer.prettyPrintRange(yylstack[yysp - 1]), yyvstack[yysp - 1].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject2, yylexer.prettyPrintRange(yylstack[yysp - 1]), yyvstack[yysp - 1].errStr)); break; case 7: @@ -1757,7 +1771,7 @@ var parser$1 = { break; default: - yyparser.yyError(rmCommonWS$2(_templateObject4, yyvstack[yysp].type, yylexer.prettyPrintRange(yylstack[yysp]))); + yyparser.yyError(rmCommonWS$3(_templateObject4, yyvstack[yysp].type, yylexer.prettyPrintRange(yylstack[yysp]))); break; } } @@ -1813,9 +1827,9 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-) - var rv = checkActionBlock(yyvstack[yysp], yylstack[yysp]); + var rv = checkActionBlock$1(yyvstack[yysp], yylstack[yysp]); if (rv) { - yyparser.yyError(rmCommonWS$2(_templateObject5, rv, yylexer.prettyPrintRange(yylstack[yysp]))); + yyparser.yyError(rmCommonWS$3(_templateObject5, rv, yylexer.prettyPrintRange(yylstack[yysp]))); } yy.actionInclude.push(yyvstack[yysp]); this.$ = null; @@ -1874,7 +1888,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject6, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject6, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); break; case 20: @@ -1886,7 +1900,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject7, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject7, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); break; case 21: @@ -1897,11 +1911,11 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,VU,-,LT,LA,-,-) - var rv = checkActionBlock(yyvstack[yysp], yylstack[yysp]); + var rv = checkActionBlock$1(yyvstack[yysp], yylstack[yysp]); var name = yyvstack[yysp - 1]; var code = yyvstack[yysp]; if (rv) { - yyparser.yyError(rmCommonWS$2(_templateObject8, name, rv, code, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]))); + yyparser.yyError(rmCommonWS$3(_templateObject8, name, rv, code, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]))); } this.$ = { type: 'codeSection', @@ -1921,7 +1935,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject9, yylexer.prettyPrintRange(yylstack[yysp - 1], yylstack[yysp - 2], yylstack[yysp]), yyvstack[yysp - 1].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject9, yylexer.prettyPrintRange(yylstack[yysp - 1], yylstack[yysp - 2], yylstack[yysp]), yyvstack[yysp - 1].errStr)); break; case 23: @@ -2066,7 +2080,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 4,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject10, yyvstack[yysp - 3].join(','), yylexer.prettyPrintRange(yylexer.mergeLocationInfo(yysp - 3, yysp), yylstack[yysp - 3]), yyvstack[yysp - 1].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject10, yyvstack[yysp - 3].join(','), yylexer.prettyPrintRange(yylexer.mergeLocationInfo(yysp - 3, yysp), yylstack[yysp - 3]), yyvstack[yysp - 1].errStr)); break; case 38: @@ -2078,7 +2092,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject11, yyvstack[yysp - 2].join(','), yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject11, yyvstack[yysp - 2].join(','), yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); break; case 39: @@ -2100,9 +2114,9 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,VU,-,LT,LA,-,-) - var rv = checkActionBlock(yyvstack[yysp], yylstack[yysp]); + var rv = checkActionBlock$1(yyvstack[yysp], yylstack[yysp]); if (rv) { - yyparser.yyError(rmCommonWS$2(_templateObject12, rv, yylexer.prettyPrintRange(yylstack[yysp]))); + yyparser.yyError(rmCommonWS$3(_templateObject12, rv, yylexer.prettyPrintRange(yylstack[yysp]))); } this.$ = [yyvstack[yysp - 1], yyvstack[yysp]]; break; @@ -2116,7 +2130,7 @@ var parser$1 = { this.$ = [yyvstack[yysp - 1], yyvstack[yysp]]; - yyparser.yyError(rmCommonWS$2(_templateObject13, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject13, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); break; case 43: @@ -2128,7 +2142,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject14, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]))); + yyparser.yyError(rmCommonWS$3(_templateObject14, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]))); break; case 44: @@ -2140,7 +2154,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject15, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]))); + yyparser.yyError(rmCommonWS$3(_templateObject15, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]))); break; case 45: @@ -2216,7 +2230,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject16, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]))); + yyparser.yyError(rmCommonWS$3(_templateObject16, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]))); break; case 53: @@ -2228,7 +2242,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject17, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject17, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); break; case 54: @@ -2266,7 +2280,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject18, yyvstack[yysp - 1].join(','), yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject18, yyvstack[yysp - 1].join(','), yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); break; case 57: @@ -2447,7 +2461,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject19, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject19, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); break; case 76: @@ -2581,7 +2595,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 3,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject20, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject20, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); break; case 95: @@ -2682,7 +2696,7 @@ var parser$1 = { // TODO ... - yyparser.yyError(rmCommonWS$2(_templateObject21, $option, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject21, $option, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 2]), yyvstack[yysp].errStr)); break; case 108: @@ -2695,7 +2709,7 @@ var parser$1 = { // TODO ... - yyparser.yyError(rmCommonWS$2(_templateObject22, yylexer.prettyPrintRange(yylstack[yysp]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject22, yylexer.prettyPrintRange(yylstack[yysp]), yyvstack[yysp].errStr)); break; case 109: @@ -2706,9 +2720,9 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 1,VT,VA,VU,-,LT,LA,-,-) - var rv = checkActionBlock(yyvstack[yysp], yylstack[yysp]); + var rv = checkActionBlock$1(yyvstack[yysp], yylstack[yysp]); if (rv) { - yyparser.yyError(rmCommonWS$2(_templateObject23, rv, yylexer.prettyPrintRange(yylstack[yysp]))); + yyparser.yyError(rmCommonWS$3(_templateObject23, rv, yylexer.prettyPrintRange(yylstack[yysp]))); } this.$ = yyvstack[yysp]; break; @@ -2725,13 +2739,13 @@ var parser$1 = { // // Note: we have already checked the first section in a previous reduction // of this rule, so we don't need to check that one again! - var rv = checkActionBlock(yyvstack[yysp - 1], yylstack[yysp - 1]); + var rv = checkActionBlock$1(yyvstack[yysp - 1], yylstack[yysp - 1]); if (rv) { - yyparser.yyError(rmCommonWS$2(_templateObject24, rv, yylexer.prettyPrintRange(yylstack[yysp - 1]))); + yyparser.yyError(rmCommonWS$3(_templateObject24, rv, yylexer.prettyPrintRange(yylstack[yysp - 1]))); } - rv = checkActionBlock(yyvstack[yysp], yylstack[yysp]); + rv = checkActionBlock$1(yyvstack[yysp], yylstack[yysp]); if (rv) { - yyparser.yyError(rmCommonWS$2(_templateObject23, rv, yylexer.prettyPrintRange(yylstack[yysp]))); + yyparser.yyError(rmCommonWS$3(_templateObject23, rv, yylexer.prettyPrintRange(yylstack[yysp]))); } this.$ = yyvstack[yysp - 2] + yyvstack[yysp - 1] + yyvstack[yysp]; break; @@ -2758,7 +2772,7 @@ var parser$1 = { // END of default action (generated by JISON mode classic/merge :: 2,VT,VA,-,-,LT,LA,-,-) - yyparser.yyError(rmCommonWS$2(_templateObject25, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject25, yylexer.prettyPrintRange(yylstack[yysp], yylstack[yysp - 1]), yyvstack[yysp].errStr)); break; case 115: @@ -2771,7 +2785,7 @@ var parser$1 = { // TODO ... - yyparser.yyError(rmCommonWS$2(_templateObject26, yylexer.prettyPrintRange(yylstack[yysp - 1]), yyvstack[yysp - 1].errStr)); + yyparser.yyError(rmCommonWS$3(_templateObject26, yylexer.prettyPrintRange(yylstack[yysp - 1]), yyvstack[yysp - 1].errStr)); break; case 151: @@ -4027,7 +4041,7 @@ var parser$1 = { }; parser$1.originalParseError = parser$1.parseError; parser$1.originalQuoteName = parser$1.quoteName; -/* lexer generated by jison-lex 0.6.1-213 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -6639,8 +6653,8 @@ var lexer = function () { }(); parser$1.lexer = lexer; -var rmCommonWS$2 = helpers.rmCommonWS; -var checkActionBlock = helpers.checkActionBlock; +var rmCommonWS$3 = helpers.rmCommonWS; +var checkActionBlock$1 = helpers.checkActionBlock; function encodeRE(s) { return s.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1').replace(/\\\\u([a-fA-F0-9]{4})/g, '\\u$1'); @@ -7689,12 +7703,12 @@ var setmgmt = { // Zachary Carter // MIT Licensed -var rmCommonWS$1 = helpers.rmCommonWS; -var camelCase$1 = helpers.camelCase; -var code_exec$1 = helpers.exec; +var rmCommonWS$2 = helpers.rmCommonWS; +var mkIdentifier$3 = helpers.mkIdentifier; +var code_exec$2 = helpers.exec; // import recast from '@gerhobbelt/recast'; // import astUtils from '@gerhobbelt/ast-util'; -var version$1 = '0.6.1-213'; // require('./package.json').version; +var version$1 = '0.6.1-215'; // require('./package.json').version; var XREGEXP_UNICODE_ESCAPE_RE = setmgmt.XREGEXP_UNICODE_ESCAPE_RE; // Matches the XRegExp Unicode escape braced part, e.g. `{Number}` @@ -7779,7 +7793,7 @@ function mkStdOptions$1() /*...args*/{ for (var p in o) { if (typeof o[p] !== 'undefined' && h.call(o, p)) { - o2[camelCase$1(p)] = o[p]; + o2[mkIdentifier$3(p)] = o[p]; } } @@ -8629,7 +8643,7 @@ function generateErrorClass() { var jisonLexerErrorDefinition = generateErrorClass(); function generateFakeXRegExpClassSrcCode() { - return rmCommonWS$1(_templateObject36); + return rmCommonWS$2(_templateObject36); } /** @constructor */ @@ -8663,7 +8677,7 @@ function RegExpLexer(dict, input, tokens, build_options) { // var lexer = { bla... }; // ``` var testcode = ['// provide a local version for test purposes:', jisonLexerErrorDefinition, '', generateFakeXRegExpClassSrcCode(), '', source, '', 'return lexer;'].join('\n'); - var lexer = code_exec$1(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { + var lexer = code_exec$2(testcode, function generated_code_exec_wrapper_regexp_lexer(sourcecode) { //console.log("===============================LEXER TEST CODE\n", sourcecode, "\n=====================END====================\n"); var lexer_f = new Function('', sourcecode); return lexer_f(); @@ -8872,7 +8886,7 @@ function getRegExpLexerPrototype() { // --- END lexer kernel --- } -RegExpLexer.prototype = new Function(rmCommonWS$1(_templateObject37, getRegExpLexerPrototype()))(); +RegExpLexer.prototype = new Function(rmCommonWS$2(_templateObject37, getRegExpLexerPrototype()))(); // The lexer code stripper, driven by optimization analysis settings and // lexer options, which cannot be changed at run-time. @@ -8894,7 +8908,7 @@ function stripUnusedLexerCode(src, opt) { var ast = helpers.parseCodeChunkToAST(src, opt); var new_src = helpers.prettyPrintAST(ast, opt); - new_src = new_src.replace(/\/\*\s*JISON-LEX-ANALYTICS-REPORT\s*\*\//g, rmCommonWS$1(_templateObject38, opt.options.backtrack_lexer, opt.options.ranges, opt.options.trackPosition, opt.parseActionsUseYYLENG, opt.parseActionsUseYYLINENO, opt.parseActionsUseYYTEXT, opt.parseActionsUseYYLOC, opt.parseActionsUseValueTracking, opt.parseActionsUseValueAssignment, opt.parseActionsUseLocationTracking, opt.parseActionsUseLocationAssignment, opt.lexerActionsUseYYLENG, opt.lexerActionsUseYYLINENO, opt.lexerActionsUseYYTEXT, opt.lexerActionsUseYYLOC, opt.lexerActionsUseParseError, opt.lexerActionsUseYYERROR, opt.lexerActionsUseLocationTracking, opt.lexerActionsUseMore, opt.lexerActionsUseUnput, opt.lexerActionsUseReject, opt.lexerActionsUseLess, opt.lexerActionsUseDisplayAPIs, opt.lexerActionsUseDescribeYYLOC)); + new_src = new_src.replace(/\/\*\s*JISON-LEX-ANALYTICS-REPORT\s*\*\//g, rmCommonWS$2(_templateObject38, opt.options.backtrack_lexer, opt.options.ranges, opt.options.trackPosition, opt.parseActionsUseYYLENG, opt.parseActionsUseYYLINENO, opt.parseActionsUseYYTEXT, opt.parseActionsUseYYLOC, opt.parseActionsUseValueTracking, opt.parseActionsUseValueAssignment, opt.parseActionsUseLocationTracking, opt.parseActionsUseLocationAssignment, opt.lexerActionsUseYYLENG, opt.lexerActionsUseYYLINENO, opt.lexerActionsUseYYTEXT, opt.lexerActionsUseYYLOC, opt.lexerActionsUseParseError, opt.lexerActionsUseYYERROR, opt.lexerActionsUseLocationTracking, opt.lexerActionsUseMore, opt.lexerActionsUseUnput, opt.lexerActionsUseReject, opt.lexerActionsUseLess, opt.lexerActionsUseDisplayAPIs, opt.lexerActionsUseDescribeYYLOC)); return new_src; } @@ -9150,7 +9164,7 @@ function generateModuleBody(opt) { if (opt.rules.length > 0 || opt.__in_rules_failure_analysis_mode__) { // we don't mind that the `test_me()` code above will have this `lexer` variable re-defined: // JavaScript is fine with that. - var code = [rmCommonWS$1(_templateObject39), '/*JISON-LEX-ANALYTICS-REPORT*/' /* slot #1: placeholder for analysis report further below */ + var code = [rmCommonWS$2(_templateObject39), '/*JISON-LEX-ANALYTICS-REPORT*/' /* slot #1: placeholder for analysis report further below */ ]; // get the RegExpLexer.prototype in source code form: @@ -9182,7 +9196,7 @@ function generateModuleBody(opt) { var simpleCaseActionClustersCode = String(opt.caseHelperInclude); var rulesCode = generateRegexesInitTableCode(opt); var conditionsCode = cleanupJSON(JSON.stringify(opt.conditions, null, 2)); - code.push(rmCommonWS$1(_templateObject40, performActionCode, simpleCaseActionClustersCode, rulesCode, conditionsCode)); + code.push(rmCommonWS$2(_templateObject40, performActionCode, simpleCaseActionClustersCode, rulesCode, conditionsCode)); opt.is_custom_lexer = false; @@ -9218,7 +9232,7 @@ function generateModuleBody(opt) { } function generateGenericHeaderComment() { - var out = rmCommonWS$1(_templateObject41, version$1); + var out = rmCommonWS$2(_templateObject41, version$1); return out; } @@ -9270,7 +9284,7 @@ function generateAMDModule(opt) { function generateESModule(opt) { opt = prepareOptions(opt); - var out = [generateGenericHeaderComment(), '', 'var lexer = (function () {', jisonLexerErrorDefinition, '', generateModuleBody(opt), '', opt.moduleInclude ? opt.moduleInclude + ';' : '', '', 'return lexer;', '})();', '', 'function yylex() {', ' return lexer.lex.apply(lexer, arguments);', '}', rmCommonWS$1(_templateObject42)]; + var out = [generateGenericHeaderComment(), '', 'var lexer = (function () {', jisonLexerErrorDefinition, '', generateModuleBody(opt), '', opt.moduleInclude ? opt.moduleInclude + ';' : '', '', 'return lexer;', '})();', '', 'function yylex() {', ' return lexer.lex.apply(lexer, arguments);', '}', rmCommonWS$2(_templateObject42)]; var src = out.join('\n') + '\n'; src = stripUnusedLexerCode(src, opt); @@ -9294,10 +9308,11 @@ RegExpLexer.generate = generate; RegExpLexer.version = version$1; RegExpLexer.defaultJisonLexOptions = defaultJisonLexOptions; RegExpLexer.mkStdOptions = mkStdOptions$1; -RegExpLexer.camelCase = camelCase$1; +RegExpLexer.camelCase = helpers.camelCase; +RegExpLexer.mkIdentifier = mkIdentifier$3; RegExpLexer.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat$1; -/* parser generated by jison 0.6.1-213 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -10591,7 +10606,7 @@ var parser$3 = { }; parser$3.originalParseError = parser$3.parseError; parser$3.originalQuoteName = parser$3.quoteName; -/* lexer generated by jison-lex 0.6.1-213 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -12685,7 +12700,7 @@ function transform(ebnf) { // hack: var assert$2; -/* parser generated by jison 0.6.1-213 */ +/* parser generated by jison 0.6.1-215 */ /* * Returns a Parser object of the following structure: @@ -16017,7 +16032,7 @@ var parser$2 = { }; parser$2.originalParseError = parser$2.parseError; parser$2.originalQuoteName = parser$2.quoteName; -/* lexer generated by jison-lex 0.6.1-213 */ +/* lexer generated by jison-lex 0.6.1-215 */ /* * Returns a Lexer object of the following structure: @@ -18466,7 +18481,7 @@ var bnf = { }; -var version$2 = '0.6.1-213'; // require('./package.json').version; +var version$2 = '0.6.1-215'; // require('./package.json').version; function parse(grammar) { return bnf.parser.parse(grammar); @@ -19248,9 +19263,9 @@ function grammarPrinter(raw, options) { // MIT Licensed var rmCommonWS = helpers.rmCommonWS; -var camelCase = helpers.camelCase; +var mkIdentifier = helpers.mkIdentifier; var code_exec = helpers.exec; -var version = '0.6.1-213'; +var version = '0.6.1-215'; var devDebug = 0; @@ -19379,7 +19394,7 @@ function mkStdOptions() { for (var p in o) { if (typeof o[p] !== 'undefined' && h.call(o, p)) { - o2[camelCase(p)] = o[p]; + o2[mkIdentifier(p)] = o[p]; } } @@ -19618,7 +19633,8 @@ function autodetectAndConvertToJSONformat(grammar, optionalLexerSection, options Jison.rmCommonWS = rmCommonWS; Jison.mkStdOptions = mkStdOptions; -Jison.camelCase = camelCase; +Jison.camelCase = helpers.camelCase; +Jison.mkIdentifier = mkIdentifier; Jison.autodetectAndConvertToJSONformat = autodetectAndConvertToJSONformat; // detect print