@ts-jison/ebnf-parser
Version:
A parser for BNF and EBNF grammars used by jison
342 lines (319 loc) • 12 kB
text/typescript
import { JisonParser, JisonParserApi, StateType, SymbolsType, TerminalsType, ProductionsType } from '@ts-jison/parser';
/**
* parser generated by @ts-jison/parser-generator 0.3.0
* @returns Parser implementing JisonParserApi and a Lexer implementing JisonLexerApi.
*/
// import {transform} from './ebnf-parser';
const transform = require('../ebnf-transform').transform;
import {Bnf, Grammar, BnfWithGrammar} from './bnf-types';
let ebnf = false;
// transform ebnf to bnf if necessary
function extend (json: Bnf, grammar: Grammar): BnfWithGrammar {
(json as BnfWithGrammar).bnf = ebnf ? transform(grammar) : grammar;
return json as BnfWithGrammar;
}
export class BnfParser extends JisonParser implements JisonParserApi {
$?: any;
symbols_: SymbolsType = {"error":2,"spec":3,"declaration_list":4,"%%":5,"grammar":6,"optional_end_block":7,"EOF":8,"CODE":9,"declaration":10,"START":11,"id":12,"LEX_BLOCK":13,"operator":14,"ACTION":15,"parse_param":16,"options":17,"OPTIONS":18,"token_list":19,"PARSE_PARAM":20,"associativity":21,"LEFT":22,"RIGHT":23,"NONASSOC":24,"symbol":25,"production_list":26,"production":27,":":28,"handle_list":29,";":30,"|":31,"handle_action":32,"handle":33,"prec":34,"action":35,"expression_suffix":36,"handle_sublist":37,"expression":38,"suffix":39,"ALIAS":40,"ID":41,"STRING":42,"(":43,")":44,"*":45,"?":46,"+":47,"PREC":48,"{":49,"action_body":50,"}":51,"ARROW_ACTION":52,"action_comments_body":53,"ACTION_BODY":54,"$accept":0,"$end":1};
terminals_: TerminalsType = {2:"error",5:"%%",8:"EOF",9:"CODE",11:"START",13:"LEX_BLOCK",15:"ACTION",18:"OPTIONS",20:"PARSE_PARAM",22:"LEFT",23:"RIGHT",24:"NONASSOC",28:":",30:";",31:"|",40:"ALIAS",41:"ID",42:"STRING",43:"(",44:")",45:"*",46:"?",47:"+",48:"PREC",49:"{",51:"}",52:"ARROW_ACTION",54:"ACTION_BODY"};
productions_: ProductionsType = [0,[3,5],[3,6],[7,0],[7,1],[4,2],[4,0],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[17,2],[16,2],[14,2],[21,1],[21,1],[21,1],[19,2],[19,1],[6,1],[26,2],[26,1],[27,4],[29,3],[29,1],[32,3],[33,2],[33,0],[37,3],[37,1],[36,3],[36,2],[38,1],[38,1],[38,3],[39,0],[39,1],[39,1],[39,1],[34,2],[34,0],[25,1],[25,1],[12,1],[35,3],[35,1],[35,1],[35,0],[50,0],[50,1],[50,5],[50,4],[53,1],[53,2]];
table: Array<StateType>;
defaultActions: {[key:number]: any} = {34:[2,1],39:[2,2]};
constructor (yy = {}, lexer = new BnfLexer(yy)) {
super(yy, lexer);
// shorten static method to just `o` for terse STATE_TABLE
const $V0=[5,11,13,15,18,20,22,23,24],$V1=[1,21],$V2=[1,26],$V3=[41,42],$V4=[5,8,41],$V5=[5,11,13,15,18,20,22,23,24,41,42],$V6=[5,11,13,15,18,20,22,23,24,30,31,41,42,49,52],$V7=[15,30,31,41,42,43,48,49,52],$V8=[2,29],$V9=[30,31],$Va=[15,30,31,49,52],$Vb=[1,46],$Vc=[1,47],$Vd=[1,48],$Ve=[15,30,31,41,42,43,44,48,49,52],$Vf=[15,30,31,40,41,42,43,44,48,49,52],$Vg=[15,30,31,40,41,42,43,44,45,46,47,48,49,52],$Vh=[31,41,42,43,44],$Vi=[49,51],$Vj=[2,50],$Vk=[1,63],$Vl=[31,44],$Vm=[1,68],$Vn=[1,69],$Vo=[49,51,54];
const o = JisonParser.expandParseTable;
this.table = [o($V0,[2,6],{3:1,4:2}),{1:[3]},{5:[1,3],10:4,11:[1,5],13:[1,6],14:7,15:[1,8],16:9,17:10,18:[1,13],20:[1,12],21:11,22:[1,14],23:[1,15],24:[1,16]},{6:17,12:20,26:18,27:19,41:$V1},o($V0,[2,5]),{12:22,41:$V1},o($V0,[2,8]),o($V0,[2,9]),o($V0,[2,10]),o($V0,[2,11]),o($V0,[2,12]),{12:25,19:23,25:24,41:$V1,42:$V2},{12:25,19:27,25:24,41:$V1,42:$V2},{12:25,19:28,25:24,41:$V1,42:$V2},o($V3,[2,16]),o($V3,[2,17]),o($V3,[2,18]),{5:[1,30],7:29,8:[2,3]},o([5,8],[2,21],{12:20,27:31,41:$V1}),o($V4,[2,23]),{28:[1,32]},o([5,11,13,15,18,20,22,23,24,28,30,31,41,42,49,52],[2,45]),o($V0,[2,7]),o($V0,[2,15],{12:25,25:33,41:$V1,42:$V2}),o($V5,[2,20]),o($V6,[2,43]),o($V6,[2,44]),o($V0,[2,14],{12:25,25:33,41:$V1,42:$V2}),o($V0,[2,13],{12:25,25:33,41:$V1,42:$V2}),{8:[1,34]},{8:[2,4],9:[1,35]},o($V4,[2,22]),o($V7,$V8,{29:36,32:37,33:38}),o($V5,[2,19]),{1:[2,1]},{8:[1,39]},{30:[1,40],31:[1,41]},o($V9,[2,26]),o($Va,[2,42],{34:42,36:43,38:45,41:$Vb,42:$Vc,43:$Vd,48:[1,44]}),{1:[2,2]},o($V4,[2,24]),o($V7,$V8,{33:38,32:49}),o($V9,[2,49],{35:50,15:[1,52],49:[1,51],52:[1,53]}),o($Ve,[2,28]),{12:25,25:54,41:$V1,42:$V2},o($Vf,[2,37],{39:55,45:[1,56],46:[1,57],47:[1,58]}),o($Vg,[2,34]),o($Vg,[2,35]),o($Vh,$V8,{37:59,33:60}),o($V9,[2,25]),o($V9,[2,27]),o($Vi,$Vj,{50:61,53:62,54:$Vk}),o($V9,[2,47]),o($V9,[2,48]),o($Va,[2,41]),o($Ve,[2,33],{40:[1,64]}),o($Vf,[2,38]),o($Vf,[2,39]),o($Vf,[2,40]),{31:[1,66],44:[1,65]},o($Vl,[2,31],{36:43,38:45,41:$Vb,42:$Vc,43:$Vd}),{49:$Vm,51:[1,67]},o($Vi,[2,51],{54:$Vn}),o($Vo,[2,54]),o($Ve,[2,32]),o($Vg,[2,36]),o($Vh,$V8,{33:70}),o($V9,[2,46]),o($Vi,$Vj,{53:62,50:71,54:$Vk}),o($Vo,[2,55]),o($Vl,[2,30],{36:43,38:45,41:$Vb,42:$Vc,43:$Vd}),{49:$Vm,51:[1,72]},o($Vi,[2,53],{53:73,54:$Vk}),o($Vi,[2,52],{54:$Vn})];
}
performAction (yytext:string, yyleng:number, yylineno:number, yy:any, yystate:number /* action[1] */, $$:any /* vstack */, _$:any /* lstack */): any {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
this.$ = $$[$0-4];
return extend(this.$, $$[$0-2]);
break;
case 2:
this.$ = $$[$0-5];
yy.addDeclaration(this.$, { include: $$[$0-1] });
return extend(this.$, $$[$0-3]);
break;
case 5:
this.$ = $$[$0-1]; yy.addDeclaration(this.$, $$[$0]);
break;
case 6:
this.$ = {};
break;
case 7:
this.$ = {start: $$[$0]};
break;
case 8:
this.$ = {lex: $$[$0]};
break;
case 9:
this.$ = {operator: $$[$0]};
break;
case 10:
this.$ = {include: $$[$0]};
break;
case 11:
this.$ = {parseParam: $$[$0]};
break;
case 12:
this.$ = {options: $$[$0]};
break;
case 13: case 14: case 21: case 43: case 47: case 51:
this.$ = $$[$0];
break;
case 15:
this.$ = [$$[$0-1]]; this.$.push.apply(this.$, $$[$0]);
break;
case 16:
this.$ = 'left';
break;
case 17:
this.$ = 'right';
break;
case 18:
this.$ = 'nonassoc';
break;
case 19:
this.$ = $$[$0-1]; this.$.push($$[$0]);
break;
case 20: case 26:
this.$ = [$$[$0]];
break;
case 22:
this.$ = $$[$0-1];
if ($$[$0][0] in this.$)
this.$[$$[$0][0]] = this.$[$$[$0][0]].concat($$[$0][1]);
else
this.$[$$[$0][0]] = $$[$0][1];
break;
case 23:
this.$ = {}; this.$[$$[$0][0]] = $$[$0][1];
break;
case 24:
this.$ = [$$[$0-3], $$[$0-1]];
break;
case 25:
this.$ = $$[$0-2]; this.$.push($$[$0]);
break;
case 27:
this.$ = [($$[$0-2].length ? $$[$0-2].join(' ') : '')];
if($$[$0]) this.$.push($$[$0]);
if($$[$0-1]) this.$.push($$[$0-1]);
if (this.$.length === 1) this.$ = this.$[0];
break;
case 28:
this.$ = $$[$0-1]; this.$.push($$[$0])
break;
case 29:
this.$ = [];
break;
case 30:
this.$ = $$[$0-2]; this.$.push($$[$0].join(' '));
break;
case 31:
this.$ = [$$[$0].join(' ')];
break;
case 32:
this.$ = $$[$0-2] + $$[$0-1] + "[" + $$[$0] + "]";
break;
case 33:
this.$ = $$[$0-1] + $$[$0];
break;
case 34:
this.$ = $$[$0];
break;
case 35:
this.$ = ebnf ? "'" + $$[$0] + "'" : $$[$0];
break;
case 36:
this.$ = '(' + $$[$0-1].join(' | ') + ')';
break;
case 37:
this.$ = ''
break;
case 41:
this.$ = {prec: $$[$0]};
break;
case 42:
this.$ = null;
break;
case 44: case 45:
this.$ = yytext;
break;
case 46:
this.$ = $$[$0-1];
break;
case 48:
this.$ = '$$ =' + $$[$0] + ';';
break;
case 49: case 50:
this.$ = '';
break;
case 52:
this.$ = $$[$0-4] + $$[$0-3] + $$[$0-2] + $$[$0-1] + $$[$0];
break;
case 53:
this.$ = $$[$0-3] + $$[$0-2] + $$[$0-1] + $$[$0];
break;
case 54:
this.$ = yytext;
break;
case 55:
this.$ = $$[$0-1]+$$[$0];
break;
}
}
}
/* generated by @ts-jison/lexer-generator 0.3.0 */
import { JisonLexer, JisonLexerApi } from '@ts-jison/lexer';
export class BnfLexer extends JisonLexer implements JisonLexerApi {
options: any = {"moduleName":"Bnf"};
constructor (yy = {}) {
super(yy);
}
rules: RegExp[] = [
/^(?:%%)/,
/^(?:\()/,
/^(?:\))/,
/^(?:\*)/,
/^(?:\?)/,
/^(?:\+)/,
/^(?:\s+)/,
/^(?:\/\/.*)/,
/^(?:\/\*(?:.|\n|\r)*?\*\/)/,
/^(?:\[[a-zA-Z][a-zA-Z0-9_-]*\])/,
/^(?:[a-zA-Z][a-zA-Z0-9_-]*)/,
/^(?:"[^"]+")/,
/^(?:'[^']+')/,
/^(?::)/,
/^(?:;)/,
/^(?:\|)/,
/^(?:%%)/,
/^(?:%ebnf\b)/,
/^(?:%prec\b)/,
/^(?:%start\b)/,
/^(?:%left\b)/,
/^(?:%right\b)/,
/^(?:%nonassoc\b)/,
/^(?:%parse-param\b)/,
/^(?:%options\b)/,
/^(?:[%]lex[\w\W]*?[/]lex\b)/,
/^(?:%[a-zA-Z]+[^\r\n]*)/,
/^(?:<[a-zA-Z]*>)/,
/^(?:\{\{[\w\W]*?\}\})/,
/^(?:%\{(?:.|\r|\n)*?%\})/,
/^(?:\{)/,
/^(?:->.*)/,
/^(?:.)/,
/^(?:$)/,
/^(?:\/\*(?:.|\n|\r)*?\*\/)/,
/^(?:\/\/.*)/,
/^(?:\/[^ /]*?['"{}'][^ ]*?\/)/,
/^(?:"(?:\\\\|\\"|[^"])*")/,
/^(?:'(?:\\\\|\\'|[^'])*')/,
/^(?:[/"'][^{}/"']+)/,
/^(?:[^{}/"']+)/,
/^(?:\{)/,
/^(?:\})/,
/^(?:(?:.|\n|\r)+)/
];
conditions: any = {"bnf":{"rules":[0,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"inclusive":true},"ebnf":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"inclusive":true},"action":{"rules":[33,34,35,36,37,38,39,40,41,42],"inclusive":false},"code":{"rules":[33,43],"inclusive":false},"INITIAL":{"rules":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"inclusive":true}}
performAction (yy:any,yy_:any,$avoiding_name_collisions:any,YY_START:any): any {
var YYSTATE=YY_START;
switch($avoiding_name_collisions) {
case 0:this.pushState('code');return 5;
break;
case 1:return 43;
break;
case 2:return 44;
break;
case 3:return 45;
break;
case 4:return 46;
break;
case 5:return 47;
break;
case 6:/* skip whitespace */
break;
case 7:/* skip comment */
break;
case 8:/* skip comment */
break;
case 9:yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 40;
break;
case 10:return 41;
break;
case 11:yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 42;
break;
case 12:yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 42;
break;
case 13:return 28;
break;
case 14:return 30;
break;
case 15:return 31;
break;
case 16:this.pushState(ebnf ? 'ebnf' : 'bnf'); return 5;
break;
case 17:if (!yy.options) yy.options = {}; ebnf = yy.options.ebnf = true;
break;
case 18:return 48;
break;
case 19:return 11;
break;
case 20:return 22;
break;
case 21:return 23;
break;
case 22:return 24;
break;
case 23:return 20;
break;
case 24:return 18;
break;
case 25:return 13;
break;
case 26:/* ignore unrecognized decl */
break;
case 27:/* ignore type */
break;
case 28:yy_.yytext = yy_.yytext.substr(2, yy_.yyleng-4); return 15;
break;
case 29:yy_.yytext = yy_.yytext.substr(2, yy_.yytext.length-4); return 15;
break;
case 30:yy.depth = 0; this.pushState('action'); return 49;
break;
case 31:yy_.yytext = yy_.yytext.substr(2, yy_.yyleng-2); return 52;
break;
case 32:/* ignore bad characters */
break;
case 33:return 8;
break;
case 34:return 54;
break;
case 35:return 54;
break;
case 36:return 54; // regexp with braces or quotes (and no spaces)
break;
case 37:return 54;
break;
case 38:return 54;
break;
case 39:return 54;
break;
case 40:return 54;
break;
case 41:yy.depth++; return 49;
break;
case 42:if (yy.depth==0) this.begin(ebnf ? 'ebnf' : 'bnf'); else yy.depth--; return 51;
break;
case 43:return 9;
break;
}
}
}