jora
Version:
JavaScript object query engine
1,339 lines (1,207 loc) • 60.6 kB
JavaScript
'use strict';
/* parser generated by jison 0.4.18-remastered.7 */
const lexer = (function(){
/* Lexer generated by jison 0.4.18-remastered.7 */
const lexer = {
yy:{},
options: {"ranges":true},
rules: [/^(?:\/\/.*?(?:\n|\r\n?|\u2028|\u2029|$)|\/\*(?:.|\s)*?(?:\*\/|$))/,/^\s+/,/^\//,/^<(?!=)/,/^/,/^(?:(?:[a-zA-Z_]|\\u[0-9a-fA-F]{4})(?:[a-zA-Z_$0-9]|\\u[0-9a-fA-F]{4})*\(?)/,/^/,(input, state) => {
if (input[0] !== (state === 'template' ? '}' : '`')) {
return null;
}
for (let i = 1; i < input.length; i++) {
if (input[i] === '`') {
return i + 1;
}
if (input[i] === '$' && input[i + 1] === '{') {
return i + 2;
}
if (input[i] === '\\') {
i++;
}
}
return null;
},(input, state) => {
if (input[0] !== (state === 'template' ? '}' : '`')) {
return null;
}
for (let i = 1; i < input.length; i++) {
if (input[i] === '`') {
return i + 1;
}
if (input[i] === '$' && input[i + 1] === '{') {
return i + 2;
}
if (input[i] === '\\') {
i++;
}
}
return null;
},/^/,/^\(/,/^\)/,/^\[/,/^\]/,/^\{/,/^\}/,/^(?:(true|false|null|undefined|Infinity|NaN)\b)/,/^and\b/,/^or\b/,/^is\b/,/^has\s+no\b/,/^has\b/,/^in\b/,/^not\s+in\b/,/^not\b/,/^no\b/,/^(?:(asc|desc)(NA?|AN?)?\b)/,/^(?:(?:[a-zA-Z_]|\\u[0-9a-fA-F]{4})(?:[a-zA-Z_$0-9]|\\u[0-9a-fA-F]{4})*\()/,/^(?:\$(?:[a-zA-Z_]|\\u[0-9a-fA-F]{4})(?:[a-zA-Z_$0-9]|\\u[0-9a-fA-F]{4})*\()/,/^(?:(?:[a-zA-Z_]|\\u[0-9a-fA-F]{4})(?:[a-zA-Z_$0-9]|\\u[0-9a-fA-F]{4})*)/,/^(?:\$(?:[a-zA-Z_]|\\u[0-9a-fA-F]{4})(?:[a-zA-Z_$0-9]|\\u[0-9a-fA-F]{4})*)/,/^(?:[_\d]*\.)?[_\d]+(?:[eE][-+]?[_\d]+)?\b/,/^(?:\d*\.)?\d+(?:[eE][-+]?\d+)?\b/,/^0[xX][_0-9a-fA-F]+/,/^0[xX][0-9a-fA-F]+/,/^(?:"(?:\\[\\"]|[^"])*")/,/^(?:'(?:\\[\\']|[^'])*')/,/^(?:\/(?:\\.|[^/])+\/[gimsu]*)/,/^@/,/^#/,/^\$\$/,/^\$/,/^=>/,/^=/,/^!=/,/^~=/,/^>=/,/^<=/,/^</,/^>/,/^\.\.\(/,/^\.\(/,/^\.\[/,/^\.\.\./,/^\.\./,/^\./,/^\?\?/,/^\?/,/^,/,/^:/,/^;/,/^\-/,/^\+/,/^\*/,/^\//,/^\%/,/^(?:\|)/,/^./,/^$/],
conditions: {"preventPrimitive":{"rules":[0,1,2,3,4,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68],"inclusive":true},"preventKeyword":{"rules":[5,6],"inclusive":false},"template":{"rules":[8,9],"inclusive":false},"INITIAL":{"rules":[0,1,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68],"inclusive":true}},
performAction(yy,yy_,__lexelActionId,YY_START) {
const YYSTATE=YY_START;
switch (__lexelActionId) {
case 0:{yy.commentRanges.push(yy_.yylloc.range);
break;}
case 1:{
break;}
case 2:{this.popState(); return 40;
break;}
case 3:{this.popState(); return 44;
break;}
case 4:{this.done = false;
this.popState();
break;}
case 5:{this.popState();
if (yy_.yytext.endsWith('(')) {
this.unput(yy_.yytext);
return;
}
yy.pps();
return 14;
break;}
case 6:{this.done = false;
this.popState();
break;}
case 7:{const token = yy_.yytext.endsWith('`') ? 'TEMPLATE' : 'TPL_START';
yy_.yytext = this.toStringLiteral(yy_.yytext, true, 1 + Number(token !== 'TEMPLATE'));
if (token === 'TEMPLATE') {
yy.pps();
}
return token;
break;}
case 8:{const token = yy_.yytext.endsWith('`') ? 'TPL_END' : 'TPL_CONTINUE';
yy_.yytext = this.toStringLiteral(yy_.yytext, true, 1 + Number(token !== 'TPL_END'));
this.popState();
if (token === 'TPL_END') {
yy.pps();
}
return token;
break;}
case 9:{this.parseError('Unexpected end of input');
break;}
case 10:{return 21;
break;}
case 11:{yy.pps(); return 22;
break;}
case 12:{return 61;
break;}
case 13:{yy.pps(); return 63;
break;}
case 14:{return 84;
break;}
case 15:{if (this.bracketStack[this.bracketStack.length - 1] !== 'TPL_END') {
yy.pps();
return 85;
}
this.unput('}');
this.begin('template');
break;}
case 16:{yy_.yytext = this.toLiteral(yy_.yytext); // eslint-disable-line no-unused-vars
return 57;
break;}
case 17:{return 36;
break;}
case 18:{return 37;
break;}
case 19:{return 30;
break;}
case 20:{return 35;
break;}
case 21:{return 33;
break;}
case 22:{return 32;
break;}
case 23:{return 34;
break;}
case 24:{return 25;
break;}
case 25:{return 26;
break;}
case 26:{return 95;
break;}
case 27:{yy_.yytext = yy_.yytext.slice(0, -1); return 70;
break;}
case 28:{yy_.yytext = yy_.yytext.slice(1, -1); return 72;
break;}
case 29:{yy.pps(); return 14;
break;}
case 30:{yy.pps(); yy_.yytext = yy_.yytext.slice(1); return 15;
break;}
case 31:{yy.pps(); yy_.yytext = this.toNumberLiteral(yy_.yytext, true); return 55;
break;}
case 32:{yy.pps(); yy_.yytext = this.toNumberLiteral(yy_.yytext); return 55;
break;}
case 33:{yy.pps(); yy_.yytext = this.toNumberLiteral(yy_.yytext, true, true); return 55;
break;}
case 34:{yy.pps(); yy_.yytext = this.toNumberLiteral(yy_.yytext, false, true); return 55;
break;}
case 35:{yy.pps(); yy_.yytext = this.toStringLiteral(yy_.yytext); return 54;
break;}
case 36:{yy.pps(); yy_.yytext = this.toStringLiteral(yy_.yytext); return 54;
break;}
case 37:{yy.pps(); yy_.yytext = this.toRegExp(yy_.yytext); return 56;
break;}
case 38:{yy.pps(); return 51;
break;}
case 39:{yy.pps(); return 52;
break;}
case 40:{yy.pps(); return 53;
break;}
case 41:{yy.pps(); return 9;
break;}
case 42:{return 20;
break;}
case 43:{return 42;
break;}
case 44:{return 43;
break;}
case 45:{return 48;
break;}
case 46:{return 47;
break;}
case 47:{return 45;
break;}
case 48:{return 44;
break;}
case 49:{return 46;
break;}
case 50:{return 69;
break;}
case 51:{return 66;
break;}
case 52:{return 67;
break;}
case 53:{return 89;
break;}
case 54:{yy.pps(); yy.pks(); return 68;
break;}
case 55:{yy.pps(); yy.pks(); return 65;
break;}
case 56:{return 38;
break;}
case 57:{return 17;
break;}
case 58:{return 73;
break;}
case 59:{return 11;
break;}
case 60:{return 10;
break;}
case 61:{return 27;
break;}
case 62:{return 28;
break;}
case 63:{return 39;
break;}
case 64:{return 40;
break;}
case 65:{return 41;
break;}
case 66:{return 29;
break;}
case 67:{this.parseError(`Bad input on line ${yy_.yylloc.first_line} column ${yy_.yylloc.first_column}\n` + this.showPosition(), {
text: yy_.yytext,
token: 'BAD_TOKEN'
});
break;}
case 68:{return 5;
break;}
}
},
setInput(input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = false;
this._backtrack = false;
this.done = false;
this.currentCondition = 'INITIAL';
this.conditionStack = ['INITIAL'];
this.offset = 0;
this.yytext = this.match = '';
this.yyleng = 0;
this.yylineno = 0;
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (true) {
this.yylloc.range = [0, 0];
}
return this;
},
parseError(str, details) {
if (!this.yy.parser) {
throw new Error(str);
}
this.yy.parser.parseError(str, details);
},
input() {
const ch = this._input[this.offset];
const newline = /\n|\r\n?|\u2028|\u2029/g.test(ch);
this.offset++;
this.yyleng++;
this.yytext = this.match = this.yytext + ch;
if (newline) {
this.yylineno++;
this.yylloc.last_line++;
this.yylloc.last_column = 0;
} else {
this.yylloc.last_column++;
}
if (true) {
this.yylloc.range[1]++;
}
return ch;
},
lineColumnForOffset(offset = this.offset, str = this._input, startLine = 1, startColumn = 0) {
const rx = /\n|\r\n?|\u2028|\u2029/g;
let line = startLine;
let column = startColumn;
let prevLastIndex = 0;
let match;
while ((match = rx.exec(str)) !== null) {
if (match.index < offset) {
line++;
column = 0;
prevLastIndex = match.index + match[0].length;
} else {
column += offset - prevLastIndex;
prevLastIndex = -1;
break;
}
}
if (prevLastIndex !== -1) {
column += offset - prevLastIndex;
}
return {
line,
column
};
},
setMatch(start, end) {
const newMatch = this._input.slice(start, end);
const firstLoc = start !== this.offset ? this.lineColumnForOffset(start) : {
line: this.yylloc.last_line,
column: this.yylloc.last_column
};
const lastLoc = start !== end
? this.lineColumnForOffset(end - start, newMatch, firstLoc.line, firstLoc.column)
: firstLoc;
this.yytext = this.match = newMatch;
this.yyleng = end - start;
this.offset = end;
this.yylineno = lastLoc.line - 1;
this.yylloc = {
first_line: firstLoc.line,
first_column: firstLoc.column,
last_line: lastLoc.line,
last_column: lastLoc.column
};
if (true) {
this.yylloc.range = [start, end];
}
},
less(n) {
const start = this.offset - this.match.length;
this.setMatch(start, start + n);
},
unput(chunk) {
const newMatchLength = this.match.length - chunk.length;
if (!this.match.startsWith(chunk, newMatchLength)) {
throw new Error('Lexer#unput() should receive a part of matched text only');
}
this.less(newMatchLength);
},
more() {
this._more = true;
},
reject() {
if (false) {
this._backtrack = true;
return;
}
// FIXME: remove method when options.backtrack_lexer is false
throw new Error('reject() is allowed only when options.backtrack_lexer = true');
},
showPosition(offset = this.offset - this.match.length) {
const input = this._input;
const start = Math.max(offset - 20, 0);
const end = Math.min(offset + 20, input.length);
const pre = (start === 0 ? '' : '...') + input.slice(start, offset).replace(/\n|\r\n?|\u2028|\u2029/g, '\\n');
const post = input.slice(offset, end).replace(/\n|\r\n?|\u2028|\u2029/g, '\\n') + (end === input.length ? '' : '...');
return (
pre +
post +
`\n${'-'.repeat(pre.length)}^`
);
},
test_match(match, rule) {
let backup;
if (false) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.yylloc.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (true) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
this._more = false;
this._backtrack = false;
this.setMatch(this.offset, this.offset + match[0].length);
this.matches = match;
// perform action
const token = this.performAction.call(
this,
this.yy,
this,
rule,
this.conditionStack[this.conditionStack.length - 1]
);
if (!token && this._backtrack) {
// recover context
Object.assign(this, backup);
return false; // rule action called reject() implying the next rule should be tested instead.
}
if (!this.eof()) {
this.done = false;
}
if (typeof token === 'number' && this.yy.parser) {
return this.yy.parser.terminals_[token];
}
return token || false;
},
eof() {
return this.offset === this._input.length;
},
next() {
if (this.done) {
return 1; // EOF
}
if (this.eof()) {
this.done = true;
}
if (!this._more) {
this.yytext = '';
this.match = '';
}
let match;
let matchRuleId;
for (const ruleId of this.conditions[this.currentCondition].rules) {
const rule = this.rules[ruleId];
const ruleInput = this._input.slice(this.offset);
let tempMatch;
if (typeof rule === 'function') {
const ret = rule(ruleInput, this.currentCondition);
switch (typeof ret) {
case 'string': tempMatch = [ret]; break;
case 'number': tempMatch = [ruleInput.slice(0, ret)]; break;
default: tempMatch = ret;
}
} else {
tempMatch = ruleInput.match(rule);
}
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
matchRuleId = ruleId;
if (false) {
const token = this.test_match(tempMatch, matchRuleId);
if (token === false && this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
}
// when token is false this is a lexer rule which consumes
// input without producing a token (e.g. whitespace)
return token;
}
if (!false) {
break;
}
}
}
if (match) {
// when token is false this is a lexer rule which consumes
// input without producing a token (e.g. whitespace)
return this.test_match(match, matchRuleId);
}
if (this.eof()) {
return 1; // EOF
}
this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: '',
token: null,
line: this.yylineno
});
},
lex() {
let token;
while (!token) {
token = this.next();
}
return token;
},
begin(condition) {
this.currentCondition = condition;
this.conditionStack.push(condition);
},
pushState(condition) {
this.begin(condition);
},
popState() {
this.conditionStack.pop();
return this.currentCondition = (this.conditionStack.length
? this.conditionStack[this.conditionStack.length - 1]
: 'INITIAL'
);
},
topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
return n >= 0
? this.conditionStack[n]
: 'INITIAL';
},
stateStackSize() {
return this.conditionStack.length;
}
};
return lexer;
})();
;
function Parser() {
this.yy = {};
}
Parser.prototype = {Parser,
lexer,
symbols_: {"error":2,"root":3,"block":4,"EOF":5,"definitions":6,"e":7,"def":8,"$":9,";":10,":":11,"$ident":12,"ident":13,"IDENT":14,"$IDENT":15,"condConsequent":16,"?":17,"condAlternate":18,"query":19,"=>":20,"(":21,")":22,"functionArgs":23,"compareFunction":24,"NOT":25,"NO":26,"-":27,"+":28,"|":29,"IS":30,"assertion":31,"IN":32,"HAS":33,"NOTIN":34,"HASNO":35,"AND":36,"OR":37,"??":38,"*":39,"/":40,"%":41,"=":42,"!=":43,"<":44,"<=":45,">":46,">=":47,"~=":48,"queryRoot":49,"relativePath":50,"@":51,"#":52,"$$":53,"STRING":54,"NUMBER":55,"REGEXP":56,"LITERAL":57,"template":58,"object":59,"array":60,"[":61,"sliceNotation":62,"]":63,"method()":64,".":65,".(":66,".[":67,"..":68,"..(":69,"METHOD(":70,"arguments":71,"$METHOD(":72,",":73,"functionArg":74,"templateString":75,"templateStart":76,"templateTail":77,"templateEnd":78,"templateContinue":79,"TEMPLATE":80,"TPL_START":81,"TPL_CONTINUE":82,"TPL_END":83,"{":84,"}":85,"objectEntries":86,"objectEntry":87,"objectEntryKeyLiteral":88,"...":89,"arrayElements":90,"arrayElement":91,"assertionTerm":92,"assertionList":93,"compareExpr":94,"ORDER":95,"sliceNotationComponent":96,"$accept":0,"$end":1},
terminals_: {2:"error",5:"EOF",9:"$",10:";",11:":",14:"IDENT",15:"$IDENT",17:"?",20:"=>",21:"(",22:")",25:"NOT",26:"NO",27:"-",28:"+",29:"|",30:"IS",32:"IN",33:"HAS",34:"NOTIN",35:"HASNO",36:"AND",37:"OR",38:"??",39:"*",40:"/",41:"%",42:"=",43:"!=",44:"<",45:"<=",46:">",47:">=",48:"~=",51:"@",52:"#",53:"$$",54:"STRING",55:"NUMBER",56:"REGEXP",57:"LITERAL",61:"[",63:"]",65:".",66:".(",67:".[",68:"..",69:"..(",70:"METHOD(",72:"$METHOD(",73:",",80:"TEMPLATE",81:"TPL_START",82:"TPL_CONTINUE",83:"TPL_END",84:"{",85:"}",89:"...",95:"ORDER"},
productions_: [0,[3,2],[4,2],[4,1],[4,1],[4,0],[6,1],[6,2],[8,2],[8,4],[8,2],[8,4],[13,1],[12,1],[16,2],[16,1],[18,2],[18,1],[18,0],[7,1],[7,2],[7,3],[7,4],[7,5],[7,1],[7,2],[7,2],[7,2],[7,2],[7,3],[7,4],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[7,3],[19,1],[19,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,1],[49,3],[49,2],[49,2],[49,1],[49,1],[49,3],[49,4],[49,2],[49,2],[49,3],[49,3],[49,2],[49,2],[49,3],[49,2],[49,3],[50,3],[50,4],[50,4],[50,3],[50,3],[50,4],[50,4],[50,3],[50,3],[50,4],[64,2],[64,3],[64,2],[64,3],[71,1],[71,3],[74,1],[23,1],[23,3],[58,1],[58,2],[77,1],[77,2],[77,2],[77,3],[75,1],[76,1],[79,1],[78,1],[59,2],[59,3],[59,4],[59,3],[59,4],[59,5],[86,1],[86,3],[88,1],[88,1],[88,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,3],[87,3],[87,3],[87,2],[87,2],[87,2],[87,5],[87,1],[87,2],[90,1],[90,3],[91,1],[91,1],[91,2],[60,2],[60,3],[60,4],[31,1],[31,2],[31,3],[31,4],[92,1],[92,1],[92,1],[92,1],[93,1],[93,3],[93,3],[24,1],[24,3],[94,2],[62,1],[62,2],[62,2],[62,3],[96,1],[96,2]],
table: (function unpackTable(tables) {
function unpackSubtable(table) {
// restore repetitions by ref
const refs = table.match(/[\x20-\x2f]/g);
const last = refs ? Math.max(...refs.map(ref => ref.charCodeAt() - 32)) : -1;
for (let i = last; i >= 0; i--) {
const idx = (32 + i).toString(16);
let pattern;
table = table
.replace(new RegExp('\\[\\x' + idx + '(.+?)\\]'), (_, repl) => (pattern = repl))
.replace(new RegExp('\\x' + idx, 'g'), pattern);
}
// restore repetitions
table = table.replace(/<([^>]+?)>/g, (_, p) => {
let n = d64[p[0]];
let offset = 1;
if (n >> 5 === 1) {
n = (n & 0b11111) | (d64[p[1]] << 5);
offset = 2;
}
return p.slice(offset).repeat(n);
});
return table;
}
function decodeNums(encoded) {
const nums = [];
for (let j = 0; j < encoded.length; j++) {
const b1 = d64[encoded[j]];
if (b1 & 0b100000) {
const b2 = d64[encoded[++j]];
nums.push((b1 & 0b11111) | (b2 << 5));
} else {
nums.push(b1);
}
}
return nums;
}
const e64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~|=';
const d64 = e64.split('').reduce((map, ch, idx) => (map[ch] = idx, map), Object.create(null));
const [indexTable, indexRows, ...stateTables] = tables.split('=').map(unpackSubtable);
const decodedIndexRows = indexRows.split(';').map(row => {
const states = [];
for (let i = 0; i < row.length; i++) {
for (let j = 0, chunk = d64[row[i]]; j < 3; j++) {
states.push((chunk >> (j * 2)) & 0b11);
}
}
return states;
});
const decodedStateTables = stateTables.map(decodeNums);
const result = decodeNums(indexTable).map(rowIdx => {
const rowIndexes = decodedIndexRows[rowIdx];
const row = Object.create(null);
for (let i = 0; i < rowIndexes.length; i++) {
const state = rowIndexes[i];
if (state !== 0) {
const ref = decodedStateTables[state - 1].shift();
row[i] = state === 1 ? ref : [state - 1, ref];
}
}
return row;
});
for (let i = 0; i < decodedStateTables[3].length; i += 2) {
result[decodedStateTables[3][i]][decodedStateTables[3][i + 1]] = [3];
}
return result;
})("ABCDEFGHIJKHHHHLL<NM>NOPMMQRSQRTMUVWXYYMZaEFTO<TH>PMbQRSQRcMMHdefgBhBiBHj[ BjBkBk]BFHFHlBMmBnBoBpBqBrBMMsBtBMMMMXMWMMuB[!lBMMuB]vBgBMMwBUMZMxByBzB0B1B2B3B4BH5<DB6>BvBXe7BXevBgBM<E8B>9B~ <DB|>BgCgC<EhC>gCMMiC<C!>cHdjCMfMkClClCMMmCnCnBoCpCMtBqCrCvBMMMvBMUMMsCMxBHtCHtCtCHuCvCTXHXvB<FM>cHhBhBMFFMpBpCnCqCMOOMMzBzB2BMsCwCtCtCxC7BcMrCrCHMHtCtC=A1[ V[!C[\"lmkCpqC]]]<FA>[#[$[%[&['UqqWJkq]K]C][([)FgCCAAE];]]A];Ag;AwU[*ClmkOpqC]<FA>[+[,U[-qqWJnqK]]C(A]wAA[.A[/kAMAqi]]<Fq>CAAAAD<JA>g;AwADwzwP8|D<GA>||DMz|PDAwDPw;AwA8AwAMA|z<F|>DAAAIjqCMAA8MAAw;AAE!<FA>#wA8AwgMA|z<F|>DAAAMz|DMAA8MAAw;AAVClmkapqC<FA>&S(AwA8AwAMA|z<F|>DAAAMz|DIAA8MAAw;AwAoAwAMA|z<F|>DAAAMz|DMAA8MAAw;AwA8AwAMA|z<F|>DAAAMz|DMAA8MAAw;AAEi\"<FA>UqqWZmqKCFgCCgFEB;AAAChCACIAE<IA>C<KA>Q;AwAsAwBMA|z<F|>DAAAMz|DMAA8MAAw;AAAAk<QA>EAIC;AEV*<FA>#E <FA>+A <FA>#AE!<FA>%VlqCAAE;AARClC<MA>KCIEAICAAAYl;AwE~lmkOp6y<F|>X-OFg~OAA0;AwA|wzwP8|z<F|>D||DMz|PPAw|PAAw;AAEClmkKpqC<FA>'aC(AAADwzwD8|D<GA>||DMw|PDAw|D;M;AAEi\"<FA>UqqWZmqKC)B;AwA8.<Fq>CAAAMz|DMAA8MAA<Cg;AAAAAA>AI<QA>I;<FA>kAIAqi<Fq>C<OA>g;AAU!<FA>$<HA>M<QA>M;AAA8AwgMA|z<F|>DAAAMw|DM<GA>w;AwA8A0AMA6jq|qqqCAAAMz|DMAA8MAAw;AwA8A0AMA|z||q||DAAAMz|DMAA8MAAw<C;AAAAAAAAAAAAAAAAAAAAAC>AAI;AAAg<RA>D<KA>B;AAAgAkAAAqi<Fq>CAAAADAAM<GA>gB;<VA>DAAM;AAEy\"<FA>+AE!<FA>,O(AAAChCACA<KA>C<KA>Q;AAAChCACIAE<IA>C<KA>QB;<HA>I;AwA8AkAMA6i<Fq>CAAAMz|DMAA8MAAw;<FA>kAAAqi<Fq>C<JA>FoAAAg;<YA>IAAAI;AAQClC<MA>KCIEAICAAAYl;<YA>MAAAM;AAAo<UA>MAAAM;AAEq\"<FA>&OFgCOAAE;AAEi\"<FA>&OFgCOAAE;AAE!<FA>&OFgCOAAE;AAAg<UA>MAAAM;AAAClmECAgC<FA>&OFgCO;AAAw<UA>MAAAM;<FA>/<Fq>C<HA>M<GA>g;AwA8A0AMA6z||qqqCAAAMz|DMAA8MAAw;AwA8A0AMA6jqvqqqCAAAMz|DMAA8MAAw;AwA8A0AMA6jquqqqCAAAMz|DMAA8MAAw;AwA8A0AMA|z<F|>DAAAMz|DMAA8MAAw;AwA8A0AMA6z||qvqDAAAMz|DMAA8MAAw;AwA8A0AMA6z||q||DAAAMz|DMAA8MAAw;AAAgAkAAAqi<Fq><CCAAAA><FA>gB;<FA>C<SA>Q;<FA>kAAAqi<Fq>C<OA>g;AAAIAkAAAqi<Fq>C<OA>g;AAE!<FA>UqqWJmqKCFgCCgEE;<VA>D;AAAwAkAAAqi<Fq>CAAAAD<JA>g;<FA>kAAAqi<Fq>CAAAADAAM<GA>g;<HA>IAAAAK;<HA>MAAAAP;AAAClC<MA>KCIEAICAAAIl;<FA>kAAAqi<Fq>C<HA>MAAAMAAg;<FA>kAAAqi<Fq><CCAAAA><FA>g;<UA>IgqCMAAAM;AAAIAkAAAqi<Fq>C<HA>MAAAMAAg;AAAg=BC[ D[!E[\"[#F[$QhBgBG]][%[&['[(KRSbcd]iB]pBqB]T]]]]zB[)0B$%qC]y[*C[[,+[-0ChBgB]]G%]]5C4C#3C'6CpBqBT9*~*|*gD+pD-G(lD[.iBpBqB]nDqDToDzDtDuD2D4D5D6D 7D 8D9D~D gE|D\"jE-G&hEiEkETpEF[/sEtEuE]oEqEvE1E+4E-G'3EpBqBT4E-G'6EpBqBTqC8E7!zD9EuD~E+|E+gF+hF+iF+jF+kF+lF+mF+nF+oF+pF+qF+rF+sF+tF+uF+vF+wF+xFzF-G(0F.ToD1F2F3F 4F 5F6F7F qC8F+qChG0B$%jG-G&iG<EqC>kG+lG+pGqCqGrG+sG+zDtGzDwGuDvGxG+qC1G)2G3GjE-G&4GiEkET0B/8GqEvE~G+gH+hH+jH,kHRSbcd.qCqCqCpH0B$%<UqC>qGqCvH+xH<EqC>4H-G&3HT5HqCqCzDwGuD6HqCqCjE-G&~HiEkETiItEuEgIvElI+qCmI+qCqCnI+qC5C4C\"pI+qCqCqI+qCzDsIuDzDtIuD~G+iItEuEgIvE<FqC>xI+yI+qCqC=[ [![\"P[#[$[%[&['tBIsBHJ]LMNO][(oB[)fUVWXYZae]]][*jBkBlBmBnBuBvBwBxB]]r]]B]y][+B[,![-[.sB|B~B][/1B2B3B4B5B6B7B8B9BgChCiCjCkClCmCnCoCpC]]]rC]sCtCuCvCwCxCzC#B1CPtB7CsBHJ2CLMNO(*rB8C<EzC#B>hDiDjDkDzCrD%mD*rBsDyDxD1DwDvD0D3D<CtBuBvB!!>zC$mElErBrEtB1DyEzE0EwEuBvBnExEzC&)*rBzC'2ELMNO(*rBzC'5ELMNO(*rB-rC DxD1DwDvD0D<TzC#B>3DzCrD%yF*rBtBuBv<CB\">BtBuBv+zC#B9F~F|FsBgG|B~B/rC!1CzC#B<C|B~B3B4B5B6BgChCiCjCkClCmCnCoCpC><CgChCiC><CzC#B>mGnGoGrDrD-rC<CzC#B>yDxD1DuG0DyDxD1DwDvD0DzC&)*rByGzG0G.2B3B4B5B6B7B8B9BgChCiCjCkClCmCnCoCpC,mElErCzC$mElErB6G5GrEtB1DyEzE0EwEuBvB7GxEhDiDzCjD9G#BzC|G#BzC#BiHzC#BzCtB1DsBlH(*rB.2B3B4B5B6B7B8B9BgChCiCjCkClCmCnCoCpCmHnH-rCoHnH.2B3B4B5B6B7B8B9BgChCiCjCkClCmCnCoCpC!<E|B~BgChCiCjCkClCmCnCoCpC>|B~B3B4B5B6B9BgChCiCjCkClCmCnCoCpC|B~B3B4B5B6B7B9BgChCiCjCkClCmCnCoCpC|B~B3B4B5B6BgChCiCjCkClCmCnCoCp<CCgChCi><CC|B~BgChCiClCmCnCo><FC|B~BgChCi>ClCmCnCoCrD-qHrCrHsHtHuH-rCzC#BwHyHsBzH|B~B/rC-rC0H-rC1H-rCzC%2H*rBsDrD<C-rC>yDxD1DwDvD0D7H8H9H<C.2B3B4B5B6B7B8B9BgChCiCjCkClCmCnCoCpC>zC$mElErBhItB1DyEzE0EwEuBvB|HxEkIjI<CzC#B-rC>-rCzC#B-oIrCsCtCuCvCwCxC!zC#B.2B3B4B5B6B7B8B9BgChCiCjCkClCmCnCoCpC-rCzC#B-rCrI8H9H<CyDxD1DwDvD0D>zCuI#BhItB1DyEzE0EwEuBvBvIxE1H<D-rC>wI<C-rC><CzC#B><C-rC>=FDDDEEE<jBG><gBT><mBN><lBY><kB4B><kB6B><mB0B><mB1B><mB7E><mB2B><mB3B><mB5B><mB7B><mB8B><mB9B><mB~B><mB|B><mBgC><mBhC><lBS><mBlC><mBmC>FFF<mBlD><cP><5BM><mBrD><gBsD>BCCC<jBH><lBS><mB9E>FFF<PU><mB4B><mB6B>jDjDNNNiD<bN>iDN<WZ><Wa><jBb><jBc><jBI><jBK><mBtE>~EqEqEoEoEiFiFrErE<mBjC><mBwE><mB0E><mB1E><mB2E><mB3E><5BN><mBkC><cR><mBpC><mBqC><mBtC><mBuC><RwC><mBmD><mBnD><mBuD><gBtD><mBvD>1D1[ D6D6D7D7D]8D8D9D9D~D~DmEmE<D3D><D4D><D5D><RO><5B8C>gDgD<5B~C><Rd><mBf><agB><ahB><aiB><ajB><VkB><UlB><WmB><jBnB><jBoB><mBpB><mBqB><mBrB><dsB><dtB><hBuB><hBvB><hBwB><hBxB><dyB><mBzB><mByC><mB1C><mB2C><mB5C><mB6C><PV><mBnC><mB8E><mBiC><mBuE>|EgFjFjFsEsE<mBxE><D4E><RQ><mBrC><mBsC><mBvC><RxC><mBoD><mBpD><mBwD><mByD>iEiEjEjEkEkEnEnE<5B9C><5B|C><Re><mBzC><mB0C><mB3C><mB4C><mB7C><PW>kDkDiDiD<mBoC><jBJ><jBL><mBvE>pEpEqEqEhF<mByE><mBqD><mBxD>2D2 <mBzD>hEhE|D|DgEgEhDhD<PX><mBzE><D5E><D6E><mB0D>hEhElElE=BB"),
defaultActions: {50:[2,1],201:[2,159],249:[2,161]},
performAction(yytext,yyleng,yylineno,yy,yystate /* action[1] */,$$ /* vstack */,_$ /* lstack */) {
/* this == yyval */
const $0 = $$.length - 1;
switch (yystate) {
case 1:
return yy.buildResult($$[$0-1])
break;
case 2:
this.$ = {type:"Block",definitions:$$[$0-1],body:$$[$0],range:this._$.range};
break;
case 3:
this.$ = {type:"Block",definitions:$$[$0],body:{type:"Placeholder",range:[_$[$0].range[1],_$[$0].range[1]]},range:this._$.range};
break;
case 4:
this.$ = {type:"Block",definitions:[],body:$$[$0],range:this._$.range};
break;
case 5:
this.$ = {type:"Block",definitions:[],body:{type:"Placeholder",range:[_$[$0].range[1],_$[$0].range[1]]},range:this._$.range};
break;
case 6: case 96: case 99: case 101: case 117: case 136: case 152: case 155:
this.$ = [$$[$0]];
break;
case 7:
$$[$0-1].push($$[$0]);
break;
case 8:
this.$ = {type:"Definition",declarator:{type:"Declarator",name:null,range:_$[$0-1].range},value:null,range:this._$.range};
break;
case 9:
this.$ = {type:"Definition",declarator:{type:"Declarator",name:null,range:_$[$0-3].range},value:$$[$0-1],range:this._$.range};
break;
case 10:
this.$ = {type:"Definition",declarator:{type:"Declarator",name:$$[$0-1].name,range:_$[$0-1].range},value:null,range:this._$.range};
break;
case 11:
this.$ = {type:"Definition",declarator:{type:"Declarator",name:$$[$0-3].name,range:_$[$0-3].range},value:$$[$0-1],range:this._$.range};
break;
case 12: case 13: case 98: case 148: case 149:
this.$ = {type:"Identifier",name:$$[$0],range:this._$.range};
break;
case 14: case 16: case 163:
this.$ = $$[$0];
break;
case 15: case 17:
this.$ = {type:"Placeholder",range:[_$[$0].range[1],_$[$0].range[1]]};
break;
case 18: case 162:
this.$ = null;
break;
case 19: case 52: case 53: case 64: case 65: case 138:
break;
case 20: case 22:
this.$ = {type:"Function",arguments:[],body:$$[$0],range:this._$.range};
break;
case 21:
this.$ = {type:"Function",arguments:[{type:"Identifier",name:$$[$0-2],range:_$[$0-2].range}],body:$$[$0],range:this._$.range};
break;
case 23:
this.$ = {type:"Function",arguments:$$[$0-3],body:$$[$0],range:this._$.range};
break;
case 24:
this.$ = {type:"CompareFunction",compares:$$[$0],range:this._$.range};
break;
case 25: case 26: case 27: case 28: case 67:
this.$ = {type:"Prefix",operator:$$[$0-1],argument:$$[$0],range:this._$.range};
break;
case 29:
this.$ = {type:"Pipeline",left:$$[$0-2],right:$$[$0],range:this._$.range};
break;
case 30:
this.$ = {type:"Pipeline",left:$$[$0-3],right:{type:"Block",definitions:$$[$0-1],body:$$[$0]},range:this._$.range};
break;
case 31:
this.$ = {type:"Postfix",operator:$$[$0],argument:$$[$0-2],range:this._$.range};
break;
case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50:
this.$ = {type:"Binary",operator:$$[$0-1],left:$$[$0-2],right:$$[$0],range:this._$.range};
break;
case 51:
this.$ = {type:"Conditional",test:$$[$0-2],consequent:$$[$0-1],alternate:$$[$0],range:this._$.range};
break;
case 54:
this.$ = {type:"Data",range:this._$.range};
break;
case 55:
this.$ = {type:"Context",range:this._$.range};
break;
case 56:
this.$ = {type:"Current",range:this._$.range};
break;
case 57:
this.$ = {type:"Arg1",range:this._$.range};
break;
case 58:
this.$ = {type:"Reference",name:$$[$0],range:this._$.range};
break;
case 59: case 60: case 61: case 62: case 107: case 108: case 109: case 110: case 119: case 120: case 121:
this.$ = {type:"Literal",value:$$[$0],range:this._$.range};
break;
case 63:
this.$ = {type:"Template",values:$$[$0],range:this._$.range};
break;
case 66:
this.$ = {type:"SliceNotation",value:null,arguments:$$[$0-1],range:this._$.range};
break;
case 68:
this.$ = {type:"Conditional",test:null,consequent:$$[$0-1],alternate:$$[$0],range:this._$.range};
break;
case 69: case 73:
this.$ = {type:"GetProperty",value:null,property:$$[$0],range:this._$.range};
break;
case 70: case 74:
this.$ = {type:"MethodCall",value:null,method:$$[$0],range:this._$.range};
break;
case 71:
this.$ = {type:"Parentheses",body:$$[$0-1],range:this._$.range};
break;
case 72:
this.$ = {type:"Parentheses",body:{type:"Block",definitions:$$[$0-2],body:$$[$0-1]},range:this._$.range};
break;
case 75:
this.$ = {type:"Map",value:null,query:$$[$0-1],range:this._$.range};
break;
case 76:
this.$ = {type:"Filter",value:null,query:$$[$0-1],range:this._$.range};
break;
case 77:
this.$ = {type:"MapRecursive",value:null,query:{type:"GetProperty",value:null,property:$$[$0]},range:this._$.range};
break;
case 78:
this.$ = {type:"MapRecursive",value:null,query:{type:"MethodCall",value:null,method:$$[$0]},range:this._$.range};
break;
case 79:
this.$ = {type:"MapRecursive",value:null,query:$$[$0-1],range:this._$.range};
break;
case 80:
this.$ = {type:"Pipeline",left:null,right:$$[$0],range:this._$.range};
break;
case 81:
this.$ = {type:"Pipeline",left:null,right:{type:"Block",definitions:$$[$0-1],body:$$[$0]},range:this._$.range};
break;
case 82:
this.$ = {type:"Pick",value:$$[$0-2],getter:null,range:this._$.range};
break;
case 83:
this.$ = {type:"Pick",value:$$[$0-3],getter:$$[$0-1],range:this._$.range};
break;
case 84:
this.$ = {type:"SliceNotation",value:$$[$0-3],arguments:$$[$0-1],range:this._$.range};
break;
case 85:
this.$ = {type:"GetProperty",value:$$[$0-2],property:$$[$0],range:this._$.range};
break;
case 86:
this.$ = {type:"MethodCall",value:$$[$0-2],method:$$[$0],range:this._$.range};
break;
case 87:
this.$ = {type:"Map",value:$$[$0-3],query:$$[$0-1],range:this._$.range};
break;
case 88:
this.$ = {type:"Filter",value:$$[$0-3],query:$$[$0-1],range:this._$.range};
break;
case 89:
this.$ = {type:"MapRecursive",value:$$[$0-2],query:{type:"GetProperty",value:null,property:$$[$0]},range:this._$.range};
break;
case 90:
this.$ = {type:"MapRecursive",value:$$[$0-2],query:{type:"MethodCall",value:null,method:$$[$0]},range:this._$.range};
break;
case 91:
this.$ = {type:"MapRecursive",value:$$[$0-3],query:$$[$0-1],range:this._$.range};
break;
case 92:
this.$ = {type:"Method",reference:{type:"Identifier",name:$$[$0-1],range:[_$[$0-1].range[0],_$[$0-1].range[1]-1]},arguments:[],range:this._$.range};this._mn=$$[$0-1];
break;
case 93:
this.$ = {type:"Method",reference:{type:"Identifier",name:$$[$0-2],range:[_$[$0-2].range[0],_$[$0-2].range[1]-1]},arguments:$$[$0-1],range:this._$.range};this._mn=$$[$0-2];
break;
case 94:
this.$ = {type:"Method",reference:{type:"Reference",name:{type:"Identifier",name:$$[$0-1],range:[_$[$0-1].range[0],_$[$0-1].range[1]-1]},range:[_$[$0-1].range[0],_$[$0-1].range[1]-1]},arguments:[],range:this._$.range};this._mn=$$[$0-1];
break;
case 95:
this.$ = {type:"Method",reference:{type:"Reference",name:{type:"Identifier",name:$$[$0-2],range:[_$[$0-2].range[0],_$[$0-2].range[1]-1]},range:[_$[$0-2].range[0],_$[$0-2].range[1]-1]},arguments:$$[$0-1],range:this._$.range};this._mn=$$[$0-2];
break;
case 97: case 100: case 118: case 137: case 156:
$$[$0-2].push($$[$0]);
break;
case 102:
this.$=[$$[$0-1], ...$$[$0]];
break;
case 103: case 158:
this.$ = [null,$$[$0]];
break;
case 104: case 160:
this.$ = [$$[$0-1],$$[$0]];
break;
case 105:
this.$=[null, $$[$0-1], ...$$[$0]];
break;
case 106:
this.$=[$$[$0-2], $$[$0-1], ...$$[$0]];
break;
case 111: case 114:
this.$ = {type:"Object",properties:[],range:this._$.range};
break;
case 112:
this.$ = {type:"Object",properties:$$[$0-1],range:this._$.range};
break;
case 113:
this.$ = {type:"Object",properties:$$[$0-2],range:this._$.range};
break;
case 115:
this.$ = {type:"Block",definitions:$$[$0-2],body:{type:"Object",properties:$$[$0-1]},range:this._$.range};
break;
case 116:
this.$ = {type:"Block",definitions:$$[$0-3],body:{type:"Object",properties:$$[$0-2]},range:this._$.range};
break;
case 122:
this.$ = {type:"ObjectEntry",key:{type:"Current"},value:null,range:this._$.range};
break;
case 123:
this.$ = {type:"ObjectEntry",key:{type:"Reference",name:$$[$0]},value:null,range:this._$.range};
break;
case 124: case 126:
this.$ = {type:"ObjectEntry",key:$$[$0],value:null,range:this._$.range};
break;
case 125:
this.$ = {type:"ObjectEntry",key:{type:"Literal",value:this._mn},value:$$[$0],range:this._$.range};
break;
case 127: case 128:
this.$ = {type:"ObjectEntry",key:$$[$0-2],value:$$[$0],range:this._$.range};
break;
case 129:
this.$ = {type:"ObjectEntry",key:{type:"Identifier",name:"$" + $$[$0-2].name,range:_$[$0-2].range},value:$$[$0],range:this._$.range};
break;
case 130:
this.$ = {type:"ObjectEntry",key:$$[$0-1],value:{type:"Pipeline",left:{type:"Reference",name:$$[$0-1]},right:$$[$0]},range:this._$.range};
break;
case 131:
this.$ = {type:"ObjectEntry",key:$$[$0-1],value:{type:"Pipeline",left:{type:"GetProperty",value:null,property:$$[$0-1]},right:$$[$0]},range:this._$.range};
break;
case 132:
this.$ = {type:"ObjectEntry",key:{type:"Literal",value:this._mn},value:{type:"Pipeline",left:$$[$0-1],right:$$[$0]},range:this._$.range};
break;
case 133:
this.$ = {type:"ObjectEntry",key:$$[$0-3],value:$$[$0],range:this._$.range};
break;
case 134:
this.$ = {type:"Spread",query:null,array:false,range:this._$.range};
break;
case 135:
this.$ = {type:"Spread",query:$$[$0],array:false,range:this._$.range};
break;
case 139:
this.$ = {type:"Spread",query:null,array:true,range:this._$.range};
break;
case 140:
this.$ = {type:"Spread",query:$$[$0],array:true,range:this._$.range};
break;
case 141:
this.$ = {type:"Array",elements:[],range:this._$.range};
break;
case 142:
this.$ = {type:"Array",elements:$$[$0-1],range:this._$.range};
break;
case 143:
this.$ = {type:"Array",elements:$$[$0-2],range:this._$.range};
break;
case 144:
this.$ = {type:"Assertion",negation:false,assertion:$$[$0],range:this._$.range};
break;
case 145:
this.$ = {type:"Assertion",negation:true,assertion:$$[$0],range:this._$.range};
break;
case 146:
this.$ = {type:"Assertion",negation:false,assertion:$$[$0-1],range:this._$.range};
break;
case 147:
this.$ = {type:"Assertion",negation:true,assertion:$$[$0-1],range:this._$.range};
break;
case 150:
this.$ = {type:"Method",reference:{type:"Reference",name:$$[$0]},arguments:[],range:this._$.range};
break;
case 151:
this.$ = {type:"Identifier",name:String($$[$0]),range:this._$.range};
break;
case 153: case 154:
$$[$0-2].push($$[$0-1], $$[$0]);
break;
case 157:
this.$ = {type:"Compare",query:$$[$0-1],order:$$[$0],range:this._$.range};
break;
case 159:
this.$ = [null,$$[$0-1],$$[$0]];
break;
case 161:
this.$ = [$$[$0-2],$$[$0-1],$$[$0]];
break;
}
},
trace(...args) {
if (this.DEBUG) {
Jison.print(...args);
}
},
parseError(str, hash) {
if (hash.recoverable) {
this.trace(str);
} else {
const error = new Error(str);
error.hash = hash;
throw error;
}
},
parse(input, ...parseArgs) {
// use own constants for source generation reasons
const SHIFT = 1;
const REDUCE = 2;
const ACCEPT = 3;
const TERROR = 2;
const EOF = 1;
const popStack = n => {
stack.length -= 2 * n;
vstack.length -= n;
lstack.length -= n;
};
const lex = /** @replace token stack */ () => {
let token = lexer.lex() || EOF;
// if token isn't its numeric value, convert
if (typeof token !== 'number') {
token = this.symbols_[token] || token;
}
return token;
}; /** @replace */
const lexer = Object.create(this.lexer);
const ranges = lexer.options && lexer.options.ranges;
const sharedYY = { // shared state
...this.yy,
parser: this,
lexer
};
lexer.setInput(input, sharedYY);
if (typeof sharedYY.parseError === 'function') {
this.parseError = sharedYY.parseError;
}
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
const table = this.table;
const yyval = {};
let yylloc = lexer.yylloc;
const stack = [0];
const vstack = [null]; // semantic value stack
const lstack = [yylloc]; // location stack
// eslint-disable-next-line no-unused-vars
let tstack = []; // token stack, used when lex supports token stacks
let yytext = '';
let yylineno = 0;
let yyleng = 0;
let recovering = 0;
let symbol;
let preErrorSymbol;
while (true) {
// retreive state number from top of stack
let state = stack[stack.length - 1];
let action;
// use default actions if available
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
// read action for current state and first input
action = table[state] && table[state][symbol];
}
// handle parse error
if (!action || !action[0]) {
let errorRuleDepth;
let errStr = '';
// Return the rule stack depth where the nearest error rule can be found.
// Return FALSE when no error recovery rule was found.
function locateNearestErrorRecoveryRule(state) {
let stackProbe = stack.length - 1;
let depth = 0;
// try to recover from error
while (true) {
// check for error recovery rule in this state
if (TERROR.toString() in table[state]) {
return depth;
}
if (state === 0 || stackProbe < 2) {
return false; // No suitable error recovery rule available.
}
stackProbe -= 2; // popStack(1): [symbol, action]
state = stack[stackProbe];
++depth;
}
}
if (!recovering) {
// first see if there's any chance at hitting an error recovery rule:
// Report error
const expected = [];
for (const p in table[state]) {
if (p in this.terminals_ && p > TERROR) {
expected.push('\'' + this.terminals_[p] + '\'');
}
}
errStr = lexer.showPosition
? 'Parse error on line ' + (yylineno + 1) + ':\n' +
lexer.showPosition() + '\n' +
'Expecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''
: 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' +
(symbol === EOF ? 'end of input' : "'" + (this.terminals_[symbol] || symbol) + "'");
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yylloc,
expected
});
} else if (preErrorSymbol !== EOF) {
}
// just recovered from another error
if (recovering === 3) {
if (symbol === EOF || preErrorSymbol === EOF) {
throw new Error(errStr || 'Parsing halted while starting to recover from another error.');
}
// discard current lookahead and grab another
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yylloc = lexer.yylloc;
symbol = lex();
}
// try to recover from error
if (errorRuleDepth === false) {
throw new Error(errStr || 'Parsing halted. No suitable error recovery rule available.');
}
popStack(errorRuleDepth);
preErrorSymbol = symbol == TERROR ? null : symbol; // save the lookahead token
symbol = TERROR; // insert generic error symbol as new lookahead
state = stack[stack.length - 1];
action = table[state] && table[state][TERROR];
recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
}
// this shouldn't happen, unless resolve defaults are off
if (Array.isArray(action[0]) && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
}
switch (action[0]) {
case SHIFT:
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]); // push state
symbol = null;
if (!preErrorSymbol) { // normal execution/no error
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yylloc = lexer.yylloc;
if (recovering > 0) {
recovering--;
}
} else {
// error just occurred, resume old lookahead f/ before error
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case REDUCE: {
const len = this.productions_[action[1]][1];
const first = lstack[lstack.length - (len || 1)];
const last = lstack[lstack.length - 1];
// perform semantic action
yyval.$ = vstack[vstack.length - len]; // default to $$ = $1
// default location, uses first token for firsts, last for lasts
yyval._$ = {
first_line: first.first_line,
last_line: last.last_line,
first_column: first.first_column,
last_column: last.last_column
};
if (ranges) {
yyval._$.range = [
first.range[0],
last.range[1]
];
}
const actionResult = this.performAction.call(
yyval,
yytext,
yyleng,
yylineno,
sharedYY,
action[1],
vstack,
lstack,
...parseArgs
);
if (typeof actionResult !== 'undefined') {
return actionResult;
}
// pop off stack
if (len) {
popStack(len);
}
stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
vstack.push(yyval.$);
lstack.push(yyval._$);
// goto new state = table[STATE][NONTERMINAL]
stack.push(table[stack[stack.length - 2]][stack[stack.length - 1]]);
break;
}
case ACCEPT:
return true;
}
}
}};
const parser = (function buildParsers(strictParser) {
function patch(subject, patches) {
Object.entries(patches).forEach(([key, patch]) =>
subject[key] = patch(subject[key])
);
}
// better error details
const humanTokens = new Map([
['EOF', ['<end of input>']],
['IDENT', ['ident']],
['$IDENT', ['$ident']],
['NOT', ["'not'"]],
['NO', ["'no'"]],
['IS', ["'is'"]],
['IN', ["'in'"]],
['HAS', ["'has'"]],
['NOTIN', ["'not in'"]],
['HASNO', ["'has no'"]],
['AND', ["'and'"]],
['OR', ["'or'"]],
['STRING', ['string']],
['TPL_START', ['template']],
['TEMPLATE', ['template']],
['NUMBER', ['number']],
['REGEXP', ['regexp']],
['LITERAL', ["'true'", "'false'", "'null'", "'undefined'", "'NaN'", "'Infinity'"]],
['ORDER', ["'asc'", "'desc'", "'ascN'", "'descN'"]],
['METHOD(', ["'method('"]],
['$METHOD(', ["'$method('"]]
]);
const tokenForHumans = token => humanTokens.get(token) || `'${token}'`;
const parseError = function(rawMessage, details = {}, yy) {
if (details.recoverable) {
this.trace(rawMessage);
} else {
if (Array.isArray(details.inside)) {
const start = yy.lexer.offset - yy.lexer.match.length;
yy.lexer.setMatch(
start + details.inside[0],
start + details.inside[1]
);
}
const yylloc = yy.lexer.yylloc;
const message = [
rawMessage.split(/\n/)[0],
'',
yy.lexer.showPosition()
];
const expected = !Array.isArray(details.expected) ? null : [...new Set([].concat(
...details.expected.map(token => tokenForHumans(token.slice(1, -1)))
))];
if (expected) {
message.push(
'',
'Expecting ' + expected.join(', ') + ' got ' + tokenForHumans(details.token)
);
}
const error = new SyntaxError(message.join('\n'));
error.details = {
rawMessage: rawMessage,
text: details.text,
token: details.token,
expected,
loc: {
range: yylloc.range,
start: {
line: yylloc.first_line,
column: yylloc.first_column,
offset: yylloc.range[0]
},
end: {
line: yylloc.last_line,
column: yylloc.last_column,
offset: yylloc.range[1]
}
}
};
throw error;
}
};
// add new helpers to lexer
const lineTerminator = new Set(['\n', '\r', '\u2028', '\u2029']);
const literals = new Map([
['undefined', undefined],
['null', null],
['false', false],
['true', true],
['Infinity', Infinity],
['NaN', NaN]
]);
Object.assign(strictParser.lexer, {
toLiteral: value => literals.get(value),
toNumberLiteral(value, underscoped, hex = false) {
if (underscoped) {
const errorMatch = value.match(hex
? /(?:^|[^0-9a-fA-F])_|_(?:[^0-9a-fA-F]|$)/
: /(?:^|\D)_|_(?:\D|$)/
);
if (errorMatch) {
const m = errorMatch[0];
const index = errorMatch.index + Number(m[1] === '_');
const message = m === '__'
? 'Only one underscore is allowed'
: 'Wrong underscore';
this.parseError(message + ' as numeric separator', { inside: [index, index + 1] });
}
value = value.replace(/_/g, '');
}
return hex
? parseInt(value, 16)
: parseFloat(value);
},
toStringLiteral(value, multiline = false, end = 1) {
const valueEnd = value.length - end;
let result = '';
for (let i = 1; i < valueEnd; i++) {
if (!multiline && lineTerminator.has(value[i])) {
this.parseError('Invalid line terminator', { inside: [i, i + 1] });
}
if (value[i] !== '\\') {
result += value[i];
continue;
}
if (i === valueEnd - 1) {