UNPKG

imba

Version:

Intuitive and powerful language for building webapps that fly

1,354 lines (1,351 loc) 100 kB
var __commonJS = (callback, module2) => () => { if (!module2) { module2 = {exports: {}}; callback(module2.exports, module2); } return module2.exports; }; // vendor/jison/util/typal.js var require_typal = __commonJS((exports2) => { var typal2 = function() { var create = Object.create || function(o2) { function F() { } F.prototype = o2; return new F(); }; var position = /^(before|after)/; function layerMethod(k, fun) { var pos = k.match(position)[0], key = k.replace(position, ""), prop = this[key]; if (pos === "after") { this[key] = 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") { this[key] = function() { fun.apply(this, arguments); var ret = prop.apply(this, arguments); return ret; }; } } function typal_mix() { var self2 = this; for (var i = 0, o2, k; i < arguments.length; i++) { o2 = arguments[i]; if (!o2) continue; if (Object.prototype.hasOwnProperty.call(o2, "constructor")) this.constructor = o2.constructor; if (Object.prototype.hasOwnProperty.call(o2, "toString")) this.toString = o2.toString; for (k in o2) { if (Object.prototype.hasOwnProperty.call(o2, k)) { if (k.match(position) && typeof this[k.replace(position, "")] === "function") layerMethod.call(this, k, o2[k]); else this[k] = o2[k]; } } } return this; } return { mix: typal_mix, beget: function typal_beget() { return arguments.length ? typal_mix.apply(create(this), arguments) : create(this); }, construct: function typal_construct() { var o2 = typal_mix.apply(create(this), arguments); var constructor = o2.constructor; var Klass = o2.constructor = function() { return constructor.apply(this, arguments); }; Klass.prototype = o2; Klass.mix = typal_mix; return Klass; }, constructor: function typal_constructor() { return this; } }; }(); if (typeof exports2 !== "undefined") exports2.typal = typal2; }); // vendor/jison/util/set.js var require_set = __commonJS((exports2) => { var typal2 = require_typal().typal; 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); }, 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); }, union: function union(set) { return new Set2(this._items).concat(this.complement(set)); }, intersection: function intersection(set) { return this.filter(function(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, val) { return this._items[v]; }, i: function i(v, val) { return this._items[v]; }, 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 Set2(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 Set2(Array.prototype[e].apply(this._items, arguments), true); }; setMixin[e].name = e; }); var Set2 = typal2.construct(setMixin).mix({ union: function(a, b) { var ar = {}; for (var k = a.length - 1; k >= 0; --k) { ar[a[k]] = true; } for (var i = b.length - 1; i >= 0; --i) { if (!ar[b[i]]) { a.push(b[i]); } } return a; } }); if (typeof exports2 !== "undefined") exports2.Set = Set2; }); // vendor/jison/jison.js var require_jison = __commonJS((exports, module) => { var typal = require_typal().typal; var Set = require_set().Set; var Jison = exports.Jison = exports; if (typeof console !== "undefined" && console.log) { Jison.print = console.log; } else if (typeof puts !== "undefined") { Jison.print = function print2() { puts([].join.call(arguments, " ")); }; } else if (typeof print !== "undefined") { Jison.print = print; } else { Jison.print = function print2() { }; } Jison.Parser = function() { function each(obj, func) { if (obj.forEach) { obj.forEach(func); } else { var p; for (p in obj) { if (obj.hasOwnProperty(p)) { func.call(obj, obj[p], p, obj); } } } } var Nonterminal = typal.construct({ constructor: function Nonterminal(symbol) { this.symbol = symbol; this.productions = new Set(); this.first = []; this.follows = []; this.nullable = false; }, toString: function Nonterminal_toString() { var str = this.symbol + "\n"; str += this.nullable ? "nullable" : "not nullable"; str += "\nFirsts: " + this.first.join(", "); str += "\nFollows: " + this.first.join(", "); str += "\nProductions:\n " + this.productions.join("\n "); return str; } }); var Production = typal.construct({ constructor: function Production(symbol, handle, id) { this.symbol = symbol; this.handle = handle; this.nullable = false; this.id = id; this.first = []; this.precedence = 0; }, toString: function Production_toString() { return this.symbol + " -> " + this.handle.join(" "); } }); var generator = typal.beget(); generator.constructor = function Jison_Generator(grammar2, opt) { var options = typal.mix.call({}, grammar2.options, opt); this.terms = {}; this.operators = {}; this.productions = []; this.conflicts = 0; this.resolutions = []; this.options = options; this.parseParams = grammar2.parseParams; this.yy = {}; if (grammar2.actionInclude) { if (typeof grammar2.actionInclude === "function") { grammar2.actionInclude = String(grammar2.actionInclude).replace(/^\s*function \(\) \{/, "").replace(/\}\s*$/, ""); } this.actionInclude = grammar2.actionInclude; } this.moduleInclude = grammar2.moduleInclude || ""; this.DEBUG = options.debug || false; if (this.DEBUG) this.mix(generatorDebug); this.processGrammar(grammar2); }; generator.processGrammar = function processGrammarDef(grammar2) { var bnf = grammar2.bnf, tokens2 = grammar2.tokens, nonterminals = this.nonterminals = {}, productions = this.productions, self2 = this; if (tokens2) { if (typeof tokens2 === "string") { tokens2 = tokens2.trim().split(" "); } else { tokens2 = tokens2.slice(0); } } var symbols = this.symbols = []; var operators2 = this.operators = processOperators(grammar2.operators); this.buildProductions(bnf, productions, nonterminals, symbols, operators2); if (tokens2 && this.terminals.length !== tokens2.length) { self2.trace("Warning: declared tokens differ from tokens found in rules."); self2.trace(this.terminals); self2.trace(tokens2); } this.augmentGrammar(grammar2); }; generator.augmentGrammar = function augmentGrammar(grammar2) { if (this.productions.length === 0) { throw new Error("Grammar error: must have at least one rule."); } this.startSymbol = grammar2.start || grammar2.startSymbol || this.productions[0].symbol; if (!this.nonterminals[this.startSymbol]) { throw new Error("Grammar error: startSymbol must be a non-terminal found in your grammar."); } this.EOF = "$end"; var acceptProduction = new Production("$accept", [this.startSymbol, "$end"], 0); this.productions.unshift(acceptProduction); this.symbols.unshift("$accept", this.EOF); this.symbols_.$accept = 0; this.symbols_[this.EOF] = 1; this.terminals.unshift(this.EOF); this.nonterminals.$accept = new Nonterminal("$accept"); this.nonterminals.$accept.productions.push(acceptProduction); this.nonterminals[this.startSymbol].follows.push(this.EOF); }; function processOperators(ops) { if (!ops) return {}; var operators2 = {}; for (var i = 0, k, prec; prec = ops[i]; i++) { for (k = 1; k < prec.length; k++) { operators2[prec[k]] = {precedence: i + 1, assoc: prec[0]}; } } return operators2; } generator.buildProductions = function buildProductions(bnf, productions, nonterminals, symbols, operators2) { var actions = [ "/* self == yyval */", this.actionInclude || "", "var $0 = $$.length - 1;", "switch (yystate) {" ]; var actionGroups = {}; var prods, symbol; var productions_ = [0]; var symbolId = 1; var symbols_ = {}; var her = false; function addSymbol(s) { if (s && !symbols_[s]) { symbols_[s] = ++symbolId; symbols.push(s); } } addSymbol("error"); for (symbol in bnf) { if (!bnf.hasOwnProperty(symbol)) continue; addSymbol(symbol); nonterminals[symbol] = new Nonterminal(symbol); if (typeof bnf[symbol] === "string") { prods = bnf[symbol].split(/\s*\|\s*/g); } else { prods = bnf[symbol].slice(0); } prods.forEach(buildProduction); } for (var action in actionGroups) actions.push(actionGroups[action].join(" "), action, "break;"); var sym, terms = [], terms_ = {}; each(symbols_, function(id, sym2) { if (!nonterminals[sym2]) { terms.push(sym2); terms_[id] = sym2; } }); this.hasErrorRecovery = her; this.terminals = terms; this.terminals_ = terms_; this.symbols_ = symbols_; this.productions_ = productions_; actions.push("}"); actions = actions.join("\n").replace(/YYABORT/g, "return false").replace(/YYACCEPT/g, "return true"); var yyvalParam = "this"; var parameters = "self, yytext, yy, yystate /* action[1] */, $$ /* vstack */"; if (this.parseParams) parameters += ", " + this.parseParams.join(", "); this.performAction = "function performAction(" + parameters + ") {\n" + actions + "\n}"; function buildProduction(handle) { var r, rhs, i; if (handle.constructor === Array) { rhs = typeof handle[0] === "string" ? handle[0].trim().split(" ") : handle[0].slice(0); for (i = 0; i < rhs.length; i++) { if (rhs[i] === "error") her = true; if (!symbols_[rhs[i]]) { addSymbol(rhs[i]); } } if (typeof handle[1] === "string" || handle.length == 3) { var label = "case " + (productions.length + 1) + ":", action2 = handle[1]; if (action2.match(/[$@][a-zA-Z][a-zA-Z0-9_]*/)) { var count = {}, names = {}; for (i = 0; i < rhs.length; i++) { var rhs_i = rhs[i].match(/\[[a-zA-Z][a-zA-Z0-9_-]*\]/); if (rhs_i) { rhs_i = rhs_i[0].substr(1, rhs_i[0].length - 2); rhs[i] = rhs[i].substr(0, rhs[i].indexOf("[")); } else { rhs_i = rhs[i]; } if (names[rhs_i]) { names[rhs_i + ++count[rhs_i]] = i + 1; } else { names[rhs_i] = i + 1; names[rhs_i + "1"] = i + 1; count[rhs_i] = 1; } } action2 = action2.replace(/\$([a-zA-Z][a-zA-Z0-9_]*)/g, function(str, pl) { return names[pl] ? "$" + names[pl] : str; }).replace(/@([a-zA-Z][a-zA-Z0-9_]*)/g, function(str, pl) { return names[pl] ? "@" + names[pl] : str; }); } action2 = action2.replace(/([^'"])\$\$|^\$\$/g, "$1self.$").replace(/@[0$]/g, "self._$").replace(/\$(-?\d+)/g, function(_, n) { return "$$[$0" + (parseInt(n, 10) - rhs.length || "") + "]"; }).replace(/@(-?\d+)/g, function(_, n) { return "_$[$0" + (n - rhs.length || "") + "]"; }); if (action2 in actionGroups) actionGroups[action2].push(label); else actionGroups[action2] = [label]; rhs = rhs.map(function(e, i2) { return e.replace(/\[[a-zA-Z_][a-zA-Z0-9_-]*\]/g, ""); }); r = new Production(symbol, rhs, productions.length + 1); if (handle[2] && operators2[handle[2].prec]) { r.precedence = operators2[handle[2].prec].precedence; } } else { rhs = rhs.map(function(e, i2) { return e.replace(/\[[a-zA-Z_][a-zA-Z0-9_-]*\]/g, ""); }); r = new Production(symbol, rhs, productions.length + 1); if (operators2[handle[1].prec]) { r.precedence = operators2[handle[1].prec].precedence; } } } else { handle = handle.replace(/\[[a-zA-Z_][a-zA-Z0-9_-]*\]/g, ""); rhs = handle.trim().split(" "); for (i = 0; i < rhs.length; i++) { if (rhs[i] === "error") her = true; if (!symbols_[rhs[i]]) { addSymbol(rhs[i]); } } r = new Production(symbol, rhs, productions.length + 1); } if (r.precedence === 0) { for (i = r.handle.length - 1; i >= 0; i--) { if (!(r.handle[i] in nonterminals) && r.handle[i] in operators2) { r.precedence = operators2[r.handle[i]].precedence; } } } productions.push(r); productions_.push([symbols_[r.symbol], r.handle[0] === "" ? 0 : r.handle.length]); nonterminals[symbol].productions.push(r); } }; generator.createParser = function createParser() { throw new Error("Calling abstract method."); }; generator.trace = function trace() { }; generator.warn = function warn() { var args = Array.prototype.slice.call(arguments, 0); Jison.print.call(null, args.join("")); }; generator.error = function error(msg) { throw new Error(msg); }; var generatorDebug = { trace: function trace() { Jison.print.apply(null, arguments); }, beforeprocessGrammar: function() { this.trace("Processing grammar."); }, afteraugmentGrammar: function() { var trace = this.trace; each(this.symbols, function(sym, i) { trace(sym + "(" + i + ")"); }); } }; var lookaheadMixin = {}; lookaheadMixin.computeLookaheads = function computeLookaheads() { if (this.DEBUG) this.mix(lookaheadDebug); this.computeLookaheads = function() { }; this.nullableSets(); this.firstSets(); this.followSets(); }; lookaheadMixin.followSets = function followSets() { var productions = this.productions, nonterminals = this.nonterminals, self2 = this, cont = true; while (cont) { cont = false; productions.forEach(function Follow_prod_forEach(production, k) { var q; var ctx = !!self2.go_; var set = [], oldcount; for (var i = 0, t; t = production.handle[i]; ++i) { if (!nonterminals[t]) continue; if (ctx) q = self2.go_(production.symbol, production.handle.slice(0, i)); var bool = !ctx || q === parseInt(self2.nterms_[t], 10); if (i === production.handle.length + 1 && bool) { set = nonterminals[production.symbol].follows; } else { var part = production.handle.slice(i + 1); set = self2.first(part); if (self2.nullable(part) && bool) { set.push.apply(set, nonterminals[production.symbol].follows); } } oldcount = nonterminals[t].follows.length; Set.union(nonterminals[t].follows, set); if (oldcount !== nonterminals[t].follows.length) { cont = true; } } }); } }; lookaheadMixin.first = function first(symbol) { if (symbol === "") { return []; } else if (symbol instanceof Array) { var firsts = []; for (var i = 0, t; t = symbol[i]; ++i) { if (!this.nonterminals[t]) { if (firsts.indexOf(t) === -1) firsts.push(t); } else { Set.union(firsts, this.nonterminals[t].first); } if (!this.nullable(t)) break; } return firsts; } else if (!this.nonterminals[symbol]) { return [symbol]; } else { return this.nonterminals[symbol].first; } }; lookaheadMixin.firstSets = function firstSets() { var productions = this.productions, nonterminals = this.nonterminals, self2 = this, cont = true, symbol, firsts; while (cont) { cont = false; productions.forEach(function FirstSets_forEach(production, k) { var firsts2 = self2.first(production.handle); if (firsts2.length !== production.first.length) { production.first = firsts2; cont = true; } }); for (symbol in nonterminals) { firsts = []; nonterminals[symbol].productions.forEach(function(production) { Set.union(firsts, production.first); }); if (firsts.length !== nonterminals[symbol].first.length) { nonterminals[symbol].first = firsts; cont = true; } } } }; lookaheadMixin.nullableSets = function nullableSets() { var firsts = this.firsts = {}, nonterminals = this.nonterminals, self2 = this, cont = true; while (cont) { cont = false; this.productions.forEach(function(production2, k) { if (!production2.nullable) { for (var i2 = 0, n = 0, t; t = production2.handle[i2]; ++i2) { if (self2.nullable(t)) n++; } if (n === i2) { production2.nullable = cont = true; } } }); for (var symbol in nonterminals) { if (!this.nullable(symbol)) { for (var i = 0, production; production = nonterminals[symbol].productions.item(i); i++) { if (production.nullable) nonterminals[symbol].nullable = cont = true; } } } } }; lookaheadMixin.nullable = function nullable(symbol) { if (symbol === "") { return true; } else if (symbol instanceof Array) { for (var i = 0, t; t = symbol[i]; ++i) { if (!this.nullable(t)) return false; } return true; } else if (!this.nonterminals[symbol]) { return false; } else { return this.nonterminals[symbol].nullable; } }; var lookaheadDebug = { beforenullableSets: function() { this.trace("Computing Nullable sets."); }, beforefirstSets: function() { this.trace("Computing First sets."); }, beforefollowSets: function() { this.trace("Computing Follow sets."); }, afterfollowSets: function() { var trace = this.trace; each(this.nonterminals, function(nt, t) { trace(nt, "\n"); }); } }; var lrGeneratorMixin = {}; lrGeneratorMixin.buildTable = function buildTable() { if (this.DEBUG) this.mix(lrGeneratorDebug); this.states = this.canonicalCollection(); this.table = this.parseTable(this.states); this.defaultActions = findDefaults(this.table); }; lrGeneratorMixin.Item = typal.construct({ constructor: function Item(production, dot, f, predecessor) { this.production = production; this.dotPosition = dot || 0; this.follows = f || []; this.predecessor = predecessor; this.id = parseInt(production.id + "a" + this.dotPosition, 36); this.markedSymbol = this.production.handle[this.dotPosition]; }, remainingHandle: function() { return this.production.handle.slice(this.dotPosition + 1); }, eq: function(e) { return e.id === this.id; }, handleToString: function() { var handle = this.production.handle.slice(0); handle[this.dotPosition] = "." + (handle[this.dotPosition] || ""); return handle.join(" "); }, toString: function() { var temp = this.production.handle.slice(0); temp[this.dotPosition] = "." + (temp[this.dotPosition] || ""); return this.production.symbol + " -> " + temp.join(" ") + (this.follows.length === 0 ? "" : " #lookaheads= " + this.follows.join(" ")); } }); lrGeneratorMixin.ItemSet = Set.prototype.construct({ afterconstructor: function() { this.reductions = []; this.goes = {}; this.edges = {}; this.shifts = false; this.inadequate = false; this.hash_ = {}; for (var i = this._items.length - 1; i >= 0; i--) { this.hash_[this._items[i].id] = true; } }, concat: function concat(set) { var a = set._items || set; for (var i = a.length - 1; i >= 0; i--) { this.hash_[a[i].id] = true; } this._items.push.apply(this._items, a); return this; }, push: function(item) { this.hash_[item.id] = true; return this._items.push(item); }, contains: function(item) { return this.hash_[item.id]; }, valueOf: function toValue() { var v = this._items.map(function(a) { return a.id; }).sort().join("|"); this.valueOf = function toValue_inner() { return v; }; return v; } }); lrGeneratorMixin.closureOperation = function closureOperation(itemSet) { var closureSet = new this.ItemSet(); var self2 = this; var set = itemSet, itemQueue, syms = {}; do { itemQueue = new Set(); closureSet.concat(set); set.forEach(function CO_set_forEach(item) { var symbol = item.markedSymbol; if (symbol && self2.nonterminals[symbol]) { if (!syms[symbol]) { self2.nonterminals[symbol].productions.forEach(function CO_nt_forEach(production) { var newItem = new self2.Item(production, 0); if (!closureSet.contains(newItem)) itemQueue.push(newItem); }); syms[symbol] = true; } } else if (!symbol) { closureSet.reductions.push(item); closureSet.inadequate = closureSet.reductions.length > 1 || closureSet.shifts; } else { closureSet.shifts = true; closureSet.inadequate = closureSet.reductions.length > 0; } }); set = itemQueue; } while (!itemQueue.isEmpty()); return closureSet; }; lrGeneratorMixin.gotoOperation = function gotoOperation(itemSet, symbol) { var gotoSet = new this.ItemSet(), self2 = this; itemSet.forEach(function goto_forEach(item, n) { if (item.markedSymbol === symbol) { gotoSet.push(new self2.Item(item.production, item.dotPosition + 1, item.follows, n)); } }); return gotoSet.isEmpty() ? gotoSet : this.closureOperation(gotoSet); }; lrGeneratorMixin.canonicalCollection = function canonicalCollection() { var item1 = new this.Item(this.productions[0], 0, [this.EOF]); var firstState = this.closureOperation(new this.ItemSet(item1)), states = new Set(firstState), marked = 0, self2 = this, itemSet; states.has = {}; states.has[firstState] = 0; while (marked !== states.size()) { itemSet = states.item(marked); marked++; itemSet.forEach(function CC_itemSet_forEach(item) { if (item.markedSymbol && item.markedSymbol !== self2.EOF) self2.canonicalCollectionInsert(item.markedSymbol, itemSet, states, marked - 1); }); } return states; }; lrGeneratorMixin.canonicalCollectionInsert = function canonicalCollectionInsert(symbol, itemSet, states, stateNum) { var g = this.gotoOperation(itemSet, symbol); if (!g.predecessors) g.predecessors = {}; if (!g.isEmpty()) { var gv = g.valueOf(), i = states.has[gv]; if (i === -1 || typeof i === "undefined") { states.has[gv] = states.size(); itemSet.edges[symbol] = states.size(); states.push(g); g.predecessors[symbol] = [stateNum]; } else { itemSet.edges[symbol] = i; states.item(i).predecessors[symbol].push(stateNum); } } }; var NONASSOC = 0; lrGeneratorMixin.parseTable = function parseTable(itemSets) { var states = [], nonterminals = this.nonterminals, operators2 = this.operators, conflictedStates = {}, self2 = this, s = 1, r = 2, a = 3; itemSets.forEach(function(itemSet, k) { var state = states[k] = {}; var action, stackSymbol; for (stackSymbol in itemSet.edges) { itemSet.forEach(function(item, j) { if (item.markedSymbol == stackSymbol) { var gotoState = itemSet.edges[stackSymbol]; if (nonterminals[stackSymbol]) { state[self2.symbols_[stackSymbol]] = gotoState; } else { state[self2.symbols_[stackSymbol]] = [s, gotoState]; } } }); } itemSet.forEach(function(item, j) { if (item.markedSymbol == self2.EOF) { state[self2.symbols_[self2.EOF]] = [a]; } }); var allterms = self2.lookAheads ? false : self2.terminals; itemSet.reductions.forEach(function(item, j) { var terminals = allterms || self2.lookAheads(itemSet, item); terminals.forEach(function(stackSymbol2) { action = state[self2.symbols_[stackSymbol2]]; var op = operators2[stackSymbol2]; if (action || action && action.length) { var sol = resolveConflict(item.production, op, [r, item.production.id], action[0] instanceof Array ? action[0] : action); self2.resolutions.push([k, stackSymbol2, sol]); if (sol.bydefault) { self2.conflicts++; if (!self2.DEBUG) { self2.warn("Conflict in grammar: multiple actions possible when lookahead token is ", stackSymbol2, " in state ", k, "\n- ", printAction(sol.r, self2), "\n- ", printAction(sol.s, self2)); conflictedStates[k] = true; } if (self2.options.noDefaultResolve) { if (!(action[0] instanceof Array)) action = [action]; action.push(sol.r); } } else { action = sol.action; } } else { action = [r, item.production.id]; } if (action && action.length) { state[self2.symbols_[stackSymbol2]] = action; } else if (action === NONASSOC) { state[self2.symbols_[stackSymbol2]] = void 0; } }); }); }); if (!self2.DEBUG && self2.conflicts > 0) { self2.warn("\nStates with conflicts:"); each(conflictedStates, function(val, state) { self2.warn("State " + state); self2.warn(" ", itemSets.item(state).join("\n ")); }); } return states; }; function findDefaults(states) { var defaults = {}; states.forEach(function(state, k) { var i = 0; for (var act in state) { if ({}.hasOwnProperty.call(state, act)) i++; } if (i === 1 && state[act][0] === 2) { defaults[k] = state[act]; } }); return defaults; } function resolveConflict(production, op, reduce, shift) { var sln = {production, operator: op, r: reduce, s: shift}, s = 1, r = 2, a = 3; if (shift[0] === r) { sln.msg = "Resolve R/R conflict (use first production declared in grammar.)"; sln.action = shift[1] < reduce[1] ? shift : reduce; if (shift[1] !== reduce[1]) sln.bydefault = true; return sln; } if (production.precedence === 0 || !op) { sln.msg = "Resolve S/R conflict (shift by default.)"; sln.bydefault = true; sln.action = shift; } else if (production.precedence < op.precedence) { sln.msg = "Resolve S/R conflict (shift for higher precedent operator.)"; sln.action = shift; } else if (production.precedence === op.precedence) { if (op.assoc === "right") { sln.msg = "Resolve S/R conflict (shift for right associative operator.)"; sln.action = shift; } else if (op.assoc === "left") { sln.msg = "Resolve S/R conflict (reduce for left associative operator.)"; sln.action = reduce; } else if (op.assoc === "nonassoc") { sln.msg = "Resolve S/R conflict (no action for non-associative operator.)"; sln.action = NONASSOC; } } else { sln.msg = "Resolve conflict (reduce for higher precedent production.)"; sln.action = reduce; } return sln; } lrGeneratorMixin.generate = function parser_generate(opt) { opt = typal.mix.call({}, this.options, opt); var code = ""; if (!opt.moduleName || !opt.moduleName.match(/^[A-Za-z_$][A-Za-z0-9_$]*$/)) { opt.moduleName = "parser"; } switch (opt.moduleType) { case "js": code = this.generateModule(opt); break; case "amd": code = this.generateAMDModule(opt); break; default: code = this.generateCommonJSModule(opt); break; } return code; }; lrGeneratorMixin.generateAMDModule = function generateAMDModule(opt) { opt = typal.mix.call({}, this.options, opt); var module2 = this.generateModule_(); var out = "\n\ndefine(function(require){\n" + module2.commonCode + "\nvar parser = " + module2.moduleCode + "\n" + this.moduleInclude + (this.lexer && this.lexer.generateModule ? "\n" + this.lexer.generateModule() + "\nparser.lexer = lexer;" : "") + "\nreturn parser;\n});"; return out; }; lrGeneratorMixin.generateCommonJSModule = function generateCommonJSModule(opt) { opt = typal.mix.call({}, this.options, opt); var moduleName = opt.moduleName || "parser"; var out = this.generateModule(opt) + "\n\n\nif (typeof require !== 'undefined' && typeof exports !== 'undefined') {\nexports.parser = " + moduleName + ";\nexports.Parser = " + moduleName + ".Parser;\nexports.parse = function () { return " + moduleName + ".parse.apply(" + moduleName + ", arguments); };\n}"; return out; }; lrGeneratorMixin.generateModule = function generateModule(opt) { opt = typal.mix.call({}, this.options, opt); var moduleName = opt.moduleName || "parser"; var out = "/* parser generated by jison-fork */\n"; out += (moduleName.match(/\./) ? moduleName : "var " + moduleName) + " = " + this.generateModuleExpr(); return out; }; lrGeneratorMixin.generateModuleExpr = function generateModuleExpr() { var out = ""; var module2 = this.generateModule_(); out += "(function(){\n"; out += module2.commonCode; out += "\nvar parser = " + module2.moduleCode; out += "\n" + this.moduleInclude; if (this.lexer && this.lexer.generateModule) { out += this.lexer.generateModule(); out += "\nparser.lexer = lexer;"; } out += "\nfunction Parser () {\n this.yy = {};\n}\nParser.prototype = parser;parser.Parser = Parser;\nreturn new Parser;\n})();"; return out; }; function addTokenStack(fn) { var parseFn = fn; return fn; } function tokenStackLex() { var token; token = tstack.pop() || lexer.lex() || EOF; if (typeof token !== "number") { if (token instanceof Array) { tstack = token; token = tstack.pop(); } token = self.symbols_[token] || token; } return token; } lrGeneratorMixin.generateModule_ = function generateModule_() { var parseFn = String(parser.parse); nextVariableId = 0; var tableCode = this.generateTableCode(this.table); var commonCode = tableCode.commonCode; var moduleCode = "{"; moduleCode += [ "trace: " + String(this.trace || parser.trace), "yy: {}", "symbols_: " + JSON.stringify(this.symbols_), "terminals_: " + JSON.stringify(this.terminals_).replace(/"([0-9]+)":/g, "$1:"), "productions_: " + JSON.stringify(this.productions_), "performAction: " + String(this.performAction), "table: " + tableCode.moduleCode, "defaultActions: " + JSON.stringify(this.defaultActions).replace(/"([0-9]+)":/g, "$1:"), "parseError: " + String(this.parseError || (this.hasErrorRecovery ? traceParseError : parser.parseError)), "parse: " + parseFn ].join(",\n"); moduleCode += "};"; return {commonCode, moduleCode}; }; lrGeneratorMixin.generateTableCode = function(table) { var moduleCode = JSON.stringify(table); var variables = [createObjectCode]; moduleCode = moduleCode.replace(/"([0-9]+)"(?=:)/g, "$1"); moduleCode = moduleCode.replace(/\{\d+:[^\}]+,\d+:[^\}]+\}/g, function(object) { var value, frequentValue, key, keys = {}, keyCount, maxKeyCount = 0, keyValue, keyValues = [], keyValueMatcher = /(\d+):([^:]+)(?=,\d+:|\})/g; while (keyValue = keyValueMatcher.exec(object)) { key = keyValue[1]; value = keyValue[2]; keyCount = 1; if (!(value in keys)) { keys[value] = [key]; } else { keyCount = keys[value].push(key); } if (keyCount > maxKeyCount) { maxKeyCount = keyCount; frequentValue = value; } } if (maxKeyCount > 1) { for (value in keys) { if (value !== frequentValue) { for (var k = keys[value], i = 0, l = k.length; i < l; i++) { keyValues.push(k[i] + ":" + value); } } } keyValues = keyValues.length ? ",{" + keyValues.join(",") + "}" : ""; object = "o([" + keys[frequentValue].join(",") + "]," + frequentValue + keyValues + ")"; } return object; }); var list; var lists = {}; var listMatcher = /\[[0-9,]+\]/g; while (list = listMatcher.exec(moduleCode)) { lists[list] = (lists[list] || 0) + 1; } moduleCode = moduleCode.replace(listMatcher, function(list2) { var listId = lists[list2]; if (typeof listId === "number") { if (listId === 1) { lists[list2] = listId = list2; } else { lists[list2] = listId = createVariable(); variables.push(listId + "=" + list2); } } return listId; }); return { commonCode: "var " + variables.join(",") + ";", moduleCode }; }; var createObjectCode = "o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o}"; function createVariable() { var id = nextVariableId++; var name = "$V"; do { name += variableTokens[id % variableTokensLength]; id = ~~(id / variableTokensLength); } while (id !== 0); return name; } var nextVariableId = 0; var variableTokens = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"; var variableTokensLength = variableTokens.length; function printAction(a, gen) { var s = a[0] == 1 ? "shift token (then go to state " + a[1] + ")" : a[0] == 2 ? "reduce by rule: " + gen.productions[a[1]] : "accept"; return s; } var lrGeneratorDebug = { beforeparseTable: function() { this.trace("Building parse table."); }, afterparseTable: function() { var self2 = this; if (this.conflicts > 0) { this.resolutions.forEach(function(r, i) { if (r[2].bydefault) { self2.warn("Conflict at state: ", r[0], ", token: ", r[1], "\n ", printAction(r[2].r, self2), "\n ", printAction(r[2].s, self2)); } }); this.trace("\n" + this.conflicts + " Conflict(s) found in grammar."); } this.trace("Done."); }, aftercanonicalCollection: function(states) { var trace = this.trace; trace("\nItem sets\n------"); states.forEach(function(state, i) { trace("\nitem set", i, "\n" + state.join("\n"), "\ntransitions -> ", JSON.stringify(state.edges)); }); } }; var parser = typal.beget(); lrGeneratorMixin.createParser = function createParser() { var p = eval(this.generateModuleExpr()); p.productions = this.productions; var self = this; function bind(method) { return function() { self.lexer = p.lexer; return self[method].apply(self, arguments); }; } p.generate = bind("generate"); p.generateAMDModule = bind("generateAMDModule"); p.generateModule = bind("generateModule"); p.generateCommonJSModule = bind("generateCommonJSModule"); return p; }; parser.trace = generator.trace; parser.warn = generator.warn; parser.error = generator.error; function traceParseError(err, hash) { this.trace(err); } function parseError(str, hash) { if (hash.recoverable) { this.trace(str); } else { throw new Error(str); } } parser.parseError = lrGeneratorMixin.parseError = parseError; parser.parse = function parse(input, script = null) { var self2 = this, stack = [0], tstack2 = [], vstack = [null], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF2 = 1; var lexer2 = Object.create(this.lexer); var yy = this.yy; lexer2.setInput(input, yy); if (typeof yy.parseError === "function") { this.parseError = yy.parseError; } else { this.parseError = Object.getPrototypeOf(this).parseError; } function popStack(n) { stack.length = stack.length - 2 * n; vstack.length = vstack.length - n; } var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; function handleError() { var error_rule_depth; var errStr = ""; function locateNearestErrorRecoveryRule(state2) { var stack_probe = stack.length - 1; var depth = 0; for (; ; ) { if (TERROR.toString() in table[state2]) { return depth; } if (state2 === 0 || stack_probe < 2) { return false; } stack_probe -= 2; state2 = stack[stack_probe]; ++depth; } } if (!recovering) { error_rule_depth = locateNearestErrorRecoveryRule(state); expected = []; var tsym = lexer2.yytext; var lastToken = tsym; var tok = self2.terminals_[symbol] || symbol; let tidx = lexer2.tokens.indexOf(tsym); let ttok = tsym; while (ttok && ttok._loc == -1) { ttok = lexer2.tokens[--tidx]; } var tloc = ttok ? ttok._loc : -1; var tend = tloc > -1 ? tloc + (ttok._len || 0) : -1; var tpos = tloc != -1 ? "[" + ttok._loc + ":" + ttok._len + "]" : "[0:0]"; if (lexer2.showPosition) { errStr = "Parse error at " + tpos + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + tok + "'"; } else { errStr = "Unexpected " + (symbol == EOF2 ? "end of input" : "'" + tok + "'"); } if (script) { let err = script.addDiagnostic("error", { message: errStr, source: "imba-parser", range: script.rangeAt(tloc, tend) }); err.raise(); } self2.parseError(errStr, { lexer: lexer2, text: lexer2.match, token: tok, offset: tloc, length: tend - tloc, start: {offset: tloc}, end: {offset: tend}, line: lexer2.yylineno, expected, recoverable: error_rule_depth !== false }); } else if (preErrorSymbol !== EOF2) { error_rule_depth = locateNearestErrorRecoveryRule(state); } if (recovering == 3) { if (symbol === EOF2 || preErrorSymbol === EOF2) { throw new Error(errStr || "Parsing halted while starting to recover from another error."); } yytext = lexer2.yytext; } if (error_rule_depth === false) { throw new Error(errStr || "Parsing halted. No suitable error recovery rule available."); } popStack(error_rule_depth); preErrorSymbol = symbol == TERROR ? null : symbol; symbol = TERROR; state = stack[stack.length - 1]; action = table[state] && table[state][TERROR]; recovering = 3; } var __sym = this.symbols_; var __prod = this.productions_; while (true) { state = stack[stack.length - 1]; if (symbol === null || typeof symbol == "undefined") { symbol = __sym[lexer2.lex()] || EOF2; } action = table[state] && table[state][symbol]; _handle_error: if (typeof action === "undefined" || !action.length || !action[0]) { handleError(); } switch (action[0]) { case 1: stack.push(symbol); stack.push(action[1]); vstack.push(lexer2.yytext); symbol = null; if (!preErrorSymbol) { yytext = lexer2.yytext; if (recovering > 0) { recovering--; } } else { symbol = preErrorSymbol; preErrorSymbol = null; } break; case 2: len = __prod[action[1]][1]; yyval.$ = vstack[vstack.length - len]; r = this.performAction(yyval, yytext, yy, action[1], vstack); if (typeof r !== "undefined") { return r; } while (len > 0) { stack.pop(); stack.pop(); vstack.pop(); len--; } stack.push(__prod[action[1]][0]); newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; stack.push(newState); vstack.push(yyval.$); break; case 3: return true; } } return true; }; parser.init = function parser_init(dict) { this.table = dict.table; this.defaultActions = dict.defaultActions; this.performAction = dict.performAction; this.productions_ = dict.productions_; this.symbols_ = dict.symbols_; this.terminals_ = dict.terminals_; }; var lr0 = generator.beget(lookaheadMixin, lrGeneratorMixin, { type: "LR(0)", afterconstructor: function lr0_afterconstructor() { this.buildTable(); } }); var LR0Generator = exports.LR0Generator = lr0.construct(); var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, { type: "LALR(1)", afterconstructor: function(grammar2, options) { if (this.DEBUG) this.mix(lrGeneratorDebug, lalrGeneratorDebug); options = options || {}; this.states = this.canonicalCollection(); this.terms_ = {}; var newg = this.newg = typal.beget(lookaheadMixin, { oldg: this, trace: this.trace, nterms_: {}, DEBUG: false, go_: function(r, B) { r = r.split(":")[0]; B = B.map(function(b) { return b.slice(b.indexOf(":") + 1); }); return this.oldg.go(r, B); } }); newg.nonterminals = {}; newg.productions = []; this.inadequateStates = []; this.onDemandLookahead = options.onDemandLookahead || false; this.buildNewGrammar(); newg.computeLookaheads(); this.unionLookaheads(); this.table = this.parseTable(this.states); this.defaultActions = findDefaults(this.table); }, lookAheads: function LALR_lookaheads(state, item) { return !!this.onDemandLookahead && !state.inadequate ? this.terminals : item.follows; }, go: function LALR_go(p, w) { var q = parseInt(p, 10); for (var i = 0; i < w.length; i++) { q = this.states.item(q).edges[w[i]] || q; } return q; }, goPath: function LALR_goPath(p, w) { var q = parseInt(p, 10), t, path = []; for (var i = 0; i < w.length; i++) { t = w[i] ? q + ":" + w[i] : ""; if (t) this.newg.nterms_[t] = q; path.push(t); q = this.states.item(q).edges[w[i]] || q; this.terms_[t] = w[i]; } return {path, endState: q}; }, buildNewGrammar: function LALR_buildNewGrammar() { var self2 = this, newg = this.newg; this.states.forEach(function(state, i) { state.forEach(function(item) { if (item.dotPosition === 0) { var symbol = i + ":" + item.production.symbol; self2.terms_[symbol] = item.production.symbol; newg.nterms_[symbol] = i; if (!newg.nonterminals[symbol]) newg.nonterminals[symbol] = new Nonterminal(symbol); var pathInfo = self2.goPath(i, item.production.handle); var p = new Production(symbol, pathInfo.path, newg.productions.length); newg.productions.push(p); newg.nonterminals[symbol].productions.push(p); var handle = item.production.handle.join(" "); var goes = self2.states.item(pathInfo.endState).goes; if (!goes[handle]) goes[handle] = []; goes[handle].push(symbol); } }); if (state.inadequate) self2.inadequateStates.push(i); }); }, unionLookaheads: function LALR_unionLookaheads() { var self2 = this, newg = this.newg, states = !!this.onDemandLookahead ? this.inadequateStates : this.states; states.forEach(function union_states_forEach(i) { var state = typeof i === "number" ? self2.states.item(i) : i, follows = []; if (state.reductions.length) state.reductions.forEach(function union_reduction_forEach(item) { var follows2 = {}; for (var k = 0; k < item.follows.length; k++) { follows2[item.follows[k]] = true; } state.goes[item.production.handle.join(" ")].forEach(function reduction_goes_forEach(symbol) { newg.nonterminals[symbol].fol