UNPKG

syntax-cli-prog

Version:

Syntactic analysis toolkit, language agnostic parsers generator.

675 lines (570 loc) 21.9 kB
/** * LR parser generated by the Syntax tool. * * https://www.npmjs.com/package/syntax-cli * * npm install -g syntax-cli * * syntax-cli --help * * To regenerate run: * * syntax-cli \ * --grammar ~/path-to-grammar-file \ * --mode <parsing-mode> \ * --output ~/path-to-output-parser-file.js */ 'use strict'; /** * Matched token text. */ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var yytext = void 0; /** * Length of the matched token text. */ var yyleng = void 0; /** * Storage object. */ var yy = {}; /** * Result of semantic action. */ var __ = void 0; /** * Result location object. */ var __loc = void 0; function yyloc(start, end) { if (!yy.options.captureLocations) { return null; } // Epsilon doesn't produce location. if (!start || !end) { return start || end; } return { startOffset: start.startOffset, endOffset: end.endOffset, startLine: start.startLine, endLine: end.endLine, startColumn: start.startColumn, endColumn: end.endColumn }; } var EOF = '$'; /** * List of productions (generated by Syntax tool). */ var productions = [[-1, 1, function (_1) { __ = _1; }], [0, 3, function (_1, _2, _3) { var spec = Object.assign({ bnf: _3 }, __bnfParserExtra); if (__bnfParserOperators.length) { spec.operators = __bnfParserOperators; } if (tokens.length) { spec.tokens = __bnfParserTokens.join(' '); } __ = spec; }], [1, 1, function (_1) { __ = _1; }], [1, 0], [2, 1, function (_1) { __ = _1; }], [2, 2], [3, 1, function (_1) { __bnfParserExtra.lex = _1; }], [3, 1, function (_1) { __bnfParserExtra.moduleInclude = _1; }], [3, 2, function (_1, _2) { __bnfParserExtra.start = _2; }], [3, 2, function (_1, _2) { __bnfParserOperators.push(['left'].concat(_2)); }], [3, 2, function (_1, _2) { __bnfParserOperators.push(['right'].concat(_2)); }], [3, 2, function (_1, _2) { __bnfParserOperators.push(['nonassoc'].concat(_2)); }], [3, 2, function (_1, _2) { var _bnfParserTokens; (_bnfParserTokens = __bnfParserTokens).push.apply(_bnfParserTokens, _toConsumableArray(_2)); }], [4, 1, function (_1) { __ = [_1]; }], [4, 2, function (_1, _2) { __ = _1;_1.push(_2); }], [5, 2, function (_1, _2) { __ = _1;__[_2[0]] = _2[1]; }], [5, 1, function (_1) { __ = {};__[_1[0]] = _1[1]; }], [6, 4, function (_1, _2, _3, _4) { __ = [_1, _3]; }], [7, 1, function (_1) { __ = _1; }], [8, 3, function (_1, _2, _3) { __ = _1;_1.push(_3); }], [8, 1, function (_1) { __ = [_1]; }], [9, 2, function (_1, _2) { __ = [_1[0], _2];_1[1] && __.push({ prec: _1[1] }); }], [10, 2, function (_1, _2) { __ = [_1, _2]; }], [10, 0, function () { __ = ''; }], [11, 2, function (_1, _2) { __ = _2; }], [11, 0], [12, 2, function (_1, _2) { __ = _1 + ' ' + _2; }], [12, 1, function (_1) { __ = _1; }], [13, 1, function (_1) { __ = _1; }], [13, 1, function (_1) { __ = _1; }], [13, 1, function (_1) { __ = _1; }], [14, 3, function (_1, _2, _3) { __ = _2; }], [14, 0, function () { __ = null; }], [15, 1, function (_1) { __ = _1; }], [15, 5, function (_1, _2, _3, _4, _5) { __ = _1 + _2 + _3 + _4 + _5; }], [15, 4, function (_1, _2, _3, _4) { __ = _1 + _2 + _3 + _4; }], [15, 0, function () { __ = ''; }], [16, 2, function (_1, _2) { __ = _1 + _2; }], [16, 1, function (_1) { __ = _1; }]]; /** * Encoded tokens map. */ var tokens = { "%%": "17", "LEX_BLOCK": "18", "MODULE_INCLUDE": "19", "%start": "20", "%left": "21", "%right": "22", "%nonassoc": "23", "%token": "24", "SPLITTER": "25", ";": "26", "ID": "27", "|": "28", "%prec": "29", "SPECIAL_CHAR": "30", "STRING": "31", "{": "32", "}": "33", "CODE": "34", "$": "35" }; /** * Parsing table (generated by Syntax tool). */ var table = [{ "0": 1, "1": 2, "2": 3, "3": 4, "17": "r3", "18": "s5", "19": "s6", "20": "s7", "21": "s8", "22": "s9", "23": "s10", "24": "s11" }, { "35": "acc" }, { "17": "s12" }, { "3": 45, "17": "r2", "18": "s5", "19": "s6", "20": "s7", "21": "s8", "22": "s9", "23": "s10", "24": "s11" }, { "17": "r4", "18": "r4", "19": "r4", "20": "r4", "21": "r4", "22": "r4", "23": "r4", "24": "r4" }, { "17": "r6", "18": "r6", "19": "r6", "20": "r6", "21": "r6", "22": "r6", "23": "r6", "24": "r6" }, { "17": "r7", "18": "r7", "19": "r7", "20": "r7", "21": "r7", "22": "r7", "23": "r7", "24": "r7" }, { "7": 46, "27": "s16" }, { "4": 47, "13": 48, "27": "s24", "30": "s25", "31": "s26" }, { "4": 50, "13": 48, "27": "s24", "30": "s25", "31": "s26" }, { "4": 51, "13": 48, "27": "s24", "30": "s25", "31": "s26" }, { "4": 52, "13": 48, "27": "s24", "30": "s25", "31": "s26" }, { "5": 13, "6": 14, "7": 15, "27": "s16" }, { "6": 17, "7": 15, "27": "s16", "35": "r1" }, { "27": "r16", "35": "r16" }, { "25": "s18" }, { "17": "r18", "18": "r18", "19": "r18", "20": "r18", "21": "r18", "22": "r18", "23": "r18", "24": "r18", "25": "r18" }, { "27": "r15", "35": "r15" }, { "8": 19, "9": 20, "10": 21, "12": 22, "13": 23, "26": "r23", "27": "s24", "28": "r23", "30": "s25", "31": "s26", "32": "r23" }, { "26": "s27", "28": "s28" }, { "26": "r20", "28": "r20" }, { "14": 30, "26": "r32", "28": "r32", "32": "s31" }, { "11": 41, "13": 42, "26": "r25", "27": "s24", "28": "r25", "29": "s43", "30": "s25", "31": "s26", "32": "r25" }, { "26": "r27", "27": "r27", "28": "r27", "29": "r27", "30": "r27", "31": "r27", "32": "r27" }, { "17": "r28", "18": "r28", "19": "r28", "20": "r28", "21": "r28", "22": "r28", "23": "r28", "24": "r28", "26": "r28", "27": "r28", "28": "r28", "29": "r28", "30": "r28", "31": "r28", "32": "r28" }, { "17": "r29", "18": "r29", "19": "r29", "20": "r29", "21": "r29", "22": "r29", "23": "r29", "24": "r29", "26": "r29", "27": "r29", "28": "r29", "29": "r29", "30": "r29", "31": "r29", "32": "r29" }, { "17": "r30", "18": "r30", "19": "r30", "20": "r30", "21": "r30", "22": "r30", "23": "r30", "24": "r30", "26": "r30", "27": "r30", "28": "r30", "29": "r30", "30": "r30", "31": "r30", "32": "r30" }, { "27": "r17", "35": "r17" }, { "9": 29, "10": 21, "12": 22, "13": 23, "26": "r23", "27": "s24", "28": "r23", "30": "s25", "31": "s26", "32": "r23" }, { "26": "r19", "28": "r19" }, { "26": "r21", "28": "r21" }, { "15": 32, "16": 33, "32": "r36", "33": "r36", "34": "s34" }, { "32": "s36", "33": "s35" }, { "32": "r33", "33": "r33", "34": "s40" }, { "32": "r38", "33": "r38", "34": "r38" }, { "26": "r31", "28": "r31" }, { "15": 37, "16": 33, "32": "r36", "33": "r36", "34": "s34" }, { "32": "s36", "33": "s38" }, { "16": 39, "32": "r35", "33": "r35", "34": "s34" }, { "32": "r34", "33": "r34", "34": "s40" }, { "32": "r37", "33": "r37", "34": "r37" }, { "26": "r22", "28": "r22", "32": "r22" }, { "26": "r26", "27": "r26", "28": "r26", "29": "r26", "30": "r26", "31": "r26", "32": "r26" }, { "13": 44, "27": "s24", "30": "s25", "31": "s26" }, { "26": "r24", "28": "r24", "32": "r24" }, { "17": "r5", "18": "r5", "19": "r5", "20": "r5", "21": "r5", "22": "r5", "23": "r5", "24": "r5" }, { "17": "r8", "18": "r8", "19": "r8", "20": "r8", "21": "r8", "22": "r8", "23": "r8", "24": "r8" }, { "13": 49, "17": "r9", "18": "r9", "19": "r9", "20": "r9", "21": "r9", "22": "r9", "23": "r9", "24": "r9", "27": "s24", "30": "s25", "31": "s26" }, { "17": "r13", "18": "r13", "19": "r13", "20": "r13", "21": "r13", "22": "r13", "23": "r13", "24": "r13", "27": "r13", "30": "r13", "31": "r13" }, { "17": "r14", "18": "r14", "19": "r14", "20": "r14", "21": "r14", "22": "r14", "23": "r14", "24": "r14", "27": "r14", "30": "r14", "31": "r14" }, { "13": 49, "17": "r10", "18": "r10", "19": "r10", "20": "r10", "21": "r10", "22": "r10", "23": "r10", "24": "r10", "27": "s24", "30": "s25", "31": "s26" }, { "13": 49, "17": "r11", "18": "r11", "19": "r11", "20": "r11", "21": "r11", "22": "r11", "23": "r11", "24": "r11", "27": "s24", "30": "s25", "31": "s26" }, { "13": 49, "17": "r12", "18": "r12", "19": "r12", "20": "r12", "21": "r12", "22": "r12", "23": "r12", "24": "r12", "27": "s24", "30": "s25", "31": "s26" }]; /** * Parsing stack. */ var stack = []; /** * Tokenizer instance. */ var tokenizer = void 0; /** * Generic tokenizer used by the parser in the Syntax tool. * * https://www.npmjs.com/package/syntax-cli * * See `--custom-tokinzer` to skip this generation, and use a custom one. */ var lexRules = [[/^\/\/.*/, function () {/* skip comments */}], [/^\/\*(.|\s)*?\*\//, function () {/* skip comments */}], [/^\s+/, function () {/* skip whitespace */}], [/^%start\b/, function () { return '%start'; }], [/^%prec\b/, function () { return '%prec'; }], [/^%left\b/, function () { return '%left'; }], [/^%right\b/, function () { return '%right'; }], [/^%nonassoc\b/, function () { return '%nonassoc'; }], [/^%token/, function () { return '%token'; }], [/^\/\*(.|\n|\r)*?\*\//, function () { return 'CODE'; }], [/^\/\/.*/, function () { return 'CODE'; }], [/^\/[^ \/]*?['"{}'][^ ]*?\//, function () { return 'CODE'; }], [/^"(\\\\|\\"|[^"])*"/, function () { return 'CODE'; }], [/^'(\\\\|\\'|[^'])*'/, function () { return 'CODE'; }], [/^[\/"'][^{}\/"']+/, function () { return 'CODE'; }], [/^[^{}\/"']+/, function () { return 'CODE'; }], [/^\{/, function () { yy.depth++;return '{'; }], [/^\}/, function () { if (yy.depth == 0) this.popState();else yy.depth--;return '}'; }], [/^[a-zA-Z][a-zA-Z0-9_\-']*/, function () { return 'ID'; }], [/^(?:->|:(:=)?)/, function () { return 'SPLITTER'; }], [/^;/, function () { return ';'; }], [/^\|/, function () { return '|'; }], [/^\{/, function () { yy.depth = 0;this.pushState('action');return '{'; }], [/^\}/, function () { return '}'; }], [/^%%/, function () { return '%%'; }], [/^%lex[\w\W]*?\/lex\b/, function () { yytext = yytext.slice(4, -4).trim();return 'LEX_BLOCK'; }], [/^%\{(.|\r|\n)*?%\}/, function () { yytext = yytext.slice(2, -2).trim();return 'MODULE_INCLUDE'; }], [/^\{\{[\w\W]*?\}\}/, function () { yytext = yytext.slice(2, -2);return 'CODE'; }], [/^%[a-zA-Z]+[^\r\n]*/, function () {/* skip unrecognized options */}], [/^(?:"|')([^"']*)(?:"|')/, function () { return 'STRING'; }], [/^[-+!%$#@&*(){}~`^|\\:;\/,]+/, function () { return 'SPECIAL_CHAR'; }]]; var lexRulesByConditions = { "INITIAL": [0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30], "action": [9, 10, 11, 12, 13, 14, 15, 16, 17] }; var EOF_TOKEN = { type: EOF, value: '' }; tokenizer = { initString: function initString(string) { this._string = string; this._cursor = 0; this._states = ['INITIAL']; this._tokensQueue = []; this._currentLine = 1; this._currentColumn = 0; this._currentLineBeginOffset = 0; /** * Matched token location data. */ this._tokenStartOffset = 0; this._tokenEndOffset = 0; this._tokenStartLine = 1; this._tokenEndLine = 1; this._tokenStartColumn = 0; this._tokenEndColumn = 0; return this; }, /** * Returns tokenizer states. */ getStates: function getStates() { return this._states; }, getCurrentState: function getCurrentState() { return this._states[this._states.length - 1]; }, pushState: function pushState(state) { this._states.push(state); }, begin: function begin(state) { this.pushState(state); }, popState: function popState() { if (this._states.length > 1) { return this._states.pop(); } return this._states[0]; }, getNextToken: function getNextToken() { // Something was queued, return it. if (this._tokensQueue.length > 0) { return this.onToken(this._toToken(this._tokensQueue.shift())); } if (!this.hasMoreTokens()) { return this.onToken(EOF_TOKEN); } var string = this._string.slice(this._cursor); var lexRulesForState = lexRulesByConditions[this.getCurrentState()]; for (var i = 0; i < lexRulesForState.length; i++) { var lexRuleIndex = lexRulesForState[i]; var lexRule = lexRules[lexRuleIndex]; var matched = this._match(string, lexRule[0]); // Manual handling of EOF token (the end of string). Return it // as `EOF` symbol. if (string === '' && matched === '') { this._cursor++; } if (matched !== null) { yytext = matched; yyleng = yytext.length; var token = lexRule[1].call(this); if (!token) { return this.getNextToken(); } // If multiple tokens are returned, save them to return // on next `getNextToken` call. if (Array.isArray(token)) { var tokensToQueue = token.slice(1); token = token[0]; if (tokensToQueue.length > 0) { var _tokensQueue; (_tokensQueue = this._tokensQueue).unshift.apply(_tokensQueue, _toConsumableArray(tokensToQueue)); } } return this.onToken(this._toToken(token, yytext)); } } if (this.isEOF()) { this._cursor++; return EOF_TOKEN; } this.throwUnexpectedToken(string[0], this._currentLine, this._currentColumn); }, /** * Throws default "Unexpected token" exception, showing the actual * line from the source, pointing with the ^ marker to the bad token. * In addition, shows `line:column` location. */ throwUnexpectedToken: function throwUnexpectedToken(symbol, line, column) { var lineSource = this._string.split('\n')[line - 1]; var lineData = ''; if (lineSource) { var pad = ' '.repeat(column); lineData = '\n\n' + lineSource + '\n' + pad + '^\n'; } throw new SyntaxError(lineData + 'Unexpected token: "' + symbol + '" ' + ('at ' + line + ':' + column + '.')); }, getCursor: function getCursor() { return this._cursor; }, getCurrentLine: function getCurrentLine() { return this._currentLine; }, getCurrentColumn: function getCurrentColumn() { return this._currentColumn; }, _captureLocation: function _captureLocation(matched) { var nlRe = /\n/g; // Absolute offsets. this._tokenStartOffset = this._cursor; // Line-based locations, start. this._tokenStartLine = this._currentLine; this._tokenStartColumn = this._tokenStartOffset - this._currentLineBeginOffset; // Extract `\n` in the matched token. var nlMatch = void 0; while ((nlMatch = nlRe.exec(matched)) !== null) { this._currentLine++; this._currentLineBeginOffset = this._tokenStartOffset + nlMatch.index + 1; } this._tokenEndOffset = this._cursor + matched.length; // Line-based locations, end. this._tokenEndLine = this._currentLine; this._tokenEndColumn = this._currentColumn = this._tokenEndOffset - this._currentLineBeginOffset; }, _toToken: function _toToken(tokenType) { var yytext = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; return { // Basic data. type: tokenType, value: yytext, // Location data. startOffset: this._tokenStartOffset, endOffset: this._tokenEndOffset, startLine: this._tokenStartLine, endLine: this._tokenEndLine, startColumn: this._tokenStartColumn, endColumn: this._tokenEndColumn }; }, isEOF: function isEOF() { return this._cursor === this._string.length; }, hasMoreTokens: function hasMoreTokens() { return this._cursor <= this._string.length; }, _match: function _match(string, regexp) { var matched = string.match(regexp); if (matched) { // Handle `\n` in the matched token to track line numbers. this._captureLocation(matched[0]); this._cursor += matched[0].length; return matched[0]; } return null; }, /** * Allows analyzing, and transforming token. Default implementation * just passes the token through. */ onToken: function onToken(token) { return token; } }; /** * Expose tokenizer so it can be accessed in semantic actions. */ yy.lexer = tokenizer; yy.tokenizer = tokenizer; /** * Global parsing options. Some options can be shadowed per * each `parse` call, if the optations are passed. * * Initalized to the `captureLocations` which is passed * from the generator. Other options can be added at runtime. */ yy.options = { captureLocations: false }; /** * Parsing module. */ var yyparse = { /** * Sets global parsing options. */ setOptions: function setOptions(options) { yy.options = options; return this; }, /** * Returns parsing options. */ getOptions: function getOptions() { return yy.options; }, /** * Parses a string. */ parse: function parse(string, parseOptions) { if (!tokenizer) { throw new Error('Tokenizer instance wasn\'t specified.'); } tokenizer.initString(string); /** * If parse options are passed, override global parse options for * this call, and later restore global options. */ var globalOptions = yy.options; if (parseOptions) { yy.options = Object.assign({}, yy.options, parseOptions); } /** * Allow callers to do setup work based on the * parsing string, and passed options. */ yyparse.onParseBegin(string, tokenizer, yy.options); stack.length = 0; stack.push(0); var token = tokenizer.getNextToken(); var shiftedToken = null; do { if (!token) { // Restore options. yy.options = globalOptions; unexpectedEndOfInput(); } var state = stack[stack.length - 1]; var column = tokens[token.type]; if (!table[state].hasOwnProperty(column)) { yy.options = globalOptions; unexpectedToken(token); } var entry = table[state][column]; // Shift action. if (entry[0] === 's') { var loc = null; if (yy.options.captureLocations) { loc = { startOffset: token.startOffset, endOffset: token.endOffset, startLine: token.startLine, endLine: token.endLine, startColumn: token.startColumn, endColumn: token.endColumn }; } shiftedToken = this.onShift(token); stack.push({ symbol: tokens[shiftedToken.type], semanticValue: shiftedToken.value, loc: loc }, Number(entry.slice(1))); token = tokenizer.getNextToken(); } // Reduce action. else if (entry[0] === 'r') { var productionNumber = entry.slice(1); var production = productions[productionNumber]; var hasSemanticAction = typeof production[2] === 'function'; var semanticValueArgs = hasSemanticAction ? [] : null; var locationArgs = hasSemanticAction && yy.options.captureLocations ? [] : null; if (production[1] !== 0) { var rhsLength = production[1]; while (rhsLength-- > 0) { stack.pop(); var stackEntry = stack.pop(); if (hasSemanticAction) { semanticValueArgs.unshift(stackEntry.semanticValue); if (locationArgs) { locationArgs.unshift(stackEntry.loc); } } } } var reduceStackEntry = { symbol: production[0] }; if (hasSemanticAction) { yytext = shiftedToken ? shiftedToken.value : null; yyleng = shiftedToken ? shiftedToken.value.length : null; var semanticActionArgs = locationArgs !== null ? semanticValueArgs.concat(locationArgs) : semanticValueArgs; production[2].apply(production, _toConsumableArray(semanticActionArgs)); reduceStackEntry.semanticValue = __; if (locationArgs) { reduceStackEntry.loc = __loc; } } var nextState = stack[stack.length - 1]; var symbolToReduceWith = production[0]; stack.push(reduceStackEntry, table[nextState][symbolToReduceWith]); } // Accept. else if (entry === 'acc') { stack.pop(); var parsed = stack.pop(); if (stack.length !== 1 || stack[0] !== 0 || tokenizer.hasMoreTokens()) { // Restore options. yy.options = globalOptions; unexpectedToken(token); } if (parsed.hasOwnProperty('semanticValue')) { yy.options = globalOptions; yyparse.onParseEnd(parsed.semanticValue); return parsed.semanticValue; } yyparse.onParseEnd(); // Restore options. yy.options = globalOptions; return true; } } while (tokenizer.hasMoreTokens() || stack.length > 1); }, setTokenizer: function setTokenizer(customTokenizer) { tokenizer = customTokenizer; return yyparse; }, getTokenizer: function getTokenizer() { return tokenizer; }, onParseBegin: function onParseBegin(string, tokenizer, options) {}, onParseEnd: function onParseEnd(parsed) {}, /** * Allows analyzing, and transforming shifted token. Default implementation * just passes the token through. */ onShift: function onShift(token) { return token; } }; var __bnfParserTokens = void 0; var __bnfParserOperators = void 0; var __bnfParserExtra = void 0; yyparse.onParseBegin = function () { __bnfParserTokens = []; __bnfParserOperators = []; __bnfParserExtra = {}; }; function unexpectedToken(token) { if (token.type === EOF) { unexpectedEndOfInput(); } tokenizer.throwUnexpectedToken(token.value, token.startLine, token.startColumn); } function unexpectedEndOfInput() { parseError('Unexpected end of input.'); } function parseError(message) { throw new SyntaxError(message); } module.exports = yyparse;