imba
Version:
1,354 lines (1,351 loc) • 100 kB
JavaScript
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