You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3274 lines
102 KiB
3274 lines
102 KiB
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __commonJS = (cb, mod) => function __require() {
|
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
};
|
|
|
|
// vendor/jison/util/typal.js
|
|
var require_typal = __commonJS({
|
|
"vendor/jison/util/typal.js"(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({
|
|
"vendor/jison/util/set.js"(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({
|
|
"vendor/jison/jison.js"(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 p2;
|
|
for (p2 in obj) {
|
|
if (obj.hasOwnProperty(p2)) {
|
|
func.call(obj, obj[p2], p2, obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var Nonterminal = typal.construct({
|
|
constructor: function Nonterminal2(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 Production2(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 createParser2() {
|
|
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 = {}, p2, 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(p2, w) {
|
|
var q = parseInt(p2, 10);
|
|
for (var i = 0; i < w.length; i++) {
|
|
q = this.states.item(q).edges[w[i]] || q;
|
|
}
|
|
return q;
|
|
},
|
|
goPath: function LALR_goPath(p2, w) {
|
|
var q = parseInt(p2, 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 p2 = new Production(symbol, pathInfo.path, newg.productions.length);
|
|
newg.productions.push(p2);
|
|
newg.nonterminals[symbol].productions.push(p2);
|
|
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].follows.forEach(function goes_follows_forEach(symbol2) {
|
|
var terminal = self2.terms_[symbol2];
|
|
if (!follows2[terminal]) {
|
|
follows2[terminal] = true;
|
|
item.follows.push(terminal);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
});
|
|
var LALRGenerator = exports.LALRGenerator = lalr.construct();
|
|
var lalrGeneratorDebug = {
|
|
trace: function trace() {
|
|
Jison.print.apply(null, arguments);
|
|
},
|
|
beforebuildNewGrammar: function() {
|
|
this.trace(this.states.size() + " states.");
|
|
this.trace("Building lookahead grammar.");
|
|
},
|
|
beforeunionLookaheads: function() {
|
|
this.trace("Computing lookaheads.");
|
|
}
|
|
};
|
|
var lrLookaheadGenerator = generator.beget(lookaheadMixin, lrGeneratorMixin, {
|
|
afterconstructor: function lr_aftercontructor() {
|
|
this.computeLookaheads();
|
|
this.buildTable();
|
|
}
|
|
});
|
|
var SLRGenerator = exports.SLRGenerator = lrLookaheadGenerator.construct({
|
|
type: "SLR(1)",
|
|
lookAheads: function SLR_lookAhead(state, item) {
|
|
return this.nonterminals[item.production.symbol].follows;
|
|
}
|
|
});
|
|
var lr1 = lrLookaheadGenerator.beget({
|
|
type: "Canonical LR(1)",
|
|
lookAheads: function LR_lookAheads(state, item) {
|
|
return item.follows;
|
|
},
|
|
Item: lrGeneratorMixin.Item.prototype.construct({
|
|
afterconstructor: function() {
|
|
this.id = this.production.id + "a" + this.dotPosition + "a" + this.follows.sort().join(",");
|
|
},
|
|
eq: function(e) {
|
|
return e.id === this.id;
|
|
}
|
|
}),
|
|
closureOperation: function LR_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(item) {
|
|
var symbol = item.markedSymbol;
|
|
var b, r;
|
|
if (symbol && self2.nonterminals[symbol]) {
|
|
r = item.remainingHandle();
|
|
b = self2.first(item.remainingHandle());
|
|
if (b.length === 0 || item.production.nullable || self2.nullable(r)) {
|
|
b = b.concat(item.follows);
|
|
}
|
|
self2.nonterminals[symbol].productions.forEach(function(production) {
|
|
var newItem = new self2.Item(production, 0, b);
|
|
if (!closureSet.contains(newItem) && !itemQueue.contains(newItem)) {
|
|
itemQueue.push(newItem);
|
|
}
|
|
});
|
|
} else if (!symbol) {
|
|
closureSet.reductions.push(item);
|
|
}
|
|
});
|
|
set = itemQueue;
|
|
} while (!itemQueue.isEmpty());
|
|
return closureSet;
|
|
}
|
|
});
|
|
var LR1Generator = exports.LR1Generator = lr1.construct();
|
|
var ll = generator.beget(lookaheadMixin, {
|
|
type: "LL(1)",
|
|
afterconstructor: function ll_aftercontructor() {
|
|
this.computeLookaheads();
|
|
this.table = this.parseTable(this.productions);
|
|
},
|
|
parseTable: function llParseTable(productions) {
|
|
var table = {}, self2 = this;
|
|
productions.forEach(function(production, i) {
|
|
var row = table[production.symbol] || {};
|
|
var tokens2 = production.first;
|
|
if (self2.nullable(production.handle)) {
|
|
Set.union(tokens2, self2.nonterminals[production.symbol].follows);
|
|
}
|
|
tokens2.forEach(function(token) {
|
|
if (row[token]) {
|
|
row[token].push(i);
|
|
self2.conflicts++;
|
|
} else {
|
|
row[token] = [i];
|
|
}
|
|
});
|
|
table[production.symbol] = row;
|
|
});
|
|
return table;
|
|
}
|
|
});
|
|
var LLGenerator = exports.LLGenerator = ll.construct();
|
|
Jison.Generator = function Jison_Generator(g, options) {
|
|
var opt = typal.mix.call({}, g.options, options);
|
|
switch (opt.type) {
|
|
case "lr0":
|
|
return new LR0Generator(g, opt);
|
|
case "slr":
|
|
return new SLRGenerator(g, opt);
|
|
case "lr":
|
|
return new LR1Generator(g, opt);
|
|
case "ll":
|
|
return new LLGenerator(g, opt);
|
|
default:
|
|
return new LALRGenerator(g, opt);
|
|
}
|
|
};
|
|
return function Parser2(g, options) {
|
|
var gen = Jison.Generator(g, options);
|
|
return gen.createParser();
|
|
};
|
|
}();
|
|
}
|
|
});
|
|
|
|
// src/compiler/grammar.imba1
|
|
function iter$(a) {
|
|
return a ? a.toArray ? a.toArray() : a : [];
|
|
}
|
|
var jison = require_jison();
|
|
var Parser = jison.Parser;
|
|
var unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
|
|
var o = function(patternString, action, options) {
|
|
var match;
|
|
patternString = patternString.replace(/\s{2,}/g, " ");
|
|
var patternCount = patternString.split(" ").length;
|
|
if (!action) {
|
|
return [patternString, "$$ = $1;", options];
|
|
}
|
|
;
|
|
if (match = unwrap.exec(action)) {
|
|
action = match[1];
|
|
} else {
|
|
action = "(" + action + "())";
|
|
}
|
|
;
|
|
action = action.replace(/\bA(\d+)/g, "$$$1");
|
|
action = action.replace(/\bnew /g, "$&yy.");
|
|
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, "yy.$&");
|
|
action = action.replace(/\bAST\b/g, "yy");
|
|
return [patternString, "$$ = " + action + ";", options];
|
|
};
|
|
var grammar = {
|
|
Root: [
|
|
o("", function() {
|
|
return new Root([]);
|
|
}),
|
|
o("Body", function() {
|
|
return new Root(A1);
|
|
}),
|
|
o("Block TERMINATOR")
|
|
],
|
|
Body: [
|
|
o("BODYSTART", function() {
|
|
return new Block([]);
|
|
}),
|
|
o("Line", function() {
|
|
return new Block([]).add(A1);
|
|
}),
|
|
o("Body Terminator Line", function() {
|
|
return A1.break(A2).add(A3);
|
|
}),
|
|
o("Body Terminator", function() {
|
|
return A1.break(A2);
|
|
})
|
|
],
|
|
Terminator: [
|
|
o("TERMINATOR", function() {
|
|
return new Terminator(A1);
|
|
})
|
|
],
|
|
Type: [
|
|
o("TYPE", function() {
|
|
return new TypeAnnotation(A1);
|
|
})
|
|
],
|
|
Block: [
|
|
o("EMPTY_BLOCK", function() {
|
|
return new Block([]);
|
|
}),
|
|
o("INDENT OUTDENT", function() {
|
|
return new Block([]).indented(A1, A2);
|
|
}),
|
|
o("INDENT Body OUTDENT", function() {
|
|
return A2.indented(A1, A3);
|
|
}),
|
|
o("INDENT TERMINATOR Body OUTDENT", function() {
|
|
return A3.prebreak(A2).indented(A1, A4);
|
|
})
|
|
],
|
|
Line: [
|
|
o("CSSDeclaration"),
|
|
o("Expression"),
|
|
o("VarDecl", function() {
|
|
return A1.option("block", true);
|
|
}),
|
|
o("Comment"),
|
|
o("Statement"),
|
|
o("Decorators"),
|
|
o("ImportDeclaration"),
|
|
o("ExportDeclaration")
|
|
],
|
|
Statement: [
|
|
o("Return"),
|
|
o("Throw"),
|
|
o("STATEMENT", function() {
|
|
return new Literal(A1);
|
|
}),
|
|
o("BREAK", function() {
|
|
return new BreakStatement(A1);
|
|
}),
|
|
o("BREAK CALL_START Expression CALL_END", function() {
|
|
return new BreakStatement(A1, A3);
|
|
}),
|
|
o("CONTINUE", function() {
|
|
return new ContinueStatement(A1);
|
|
}),
|
|
o("CONTINUE CALL_START Expression CALL_END", function() {
|
|
return new ContinueStatement(A1, A3);
|
|
}),
|
|
o("DEBUGGER", function() {
|
|
return new DebuggerStatement(A1);
|
|
})
|
|
],
|
|
ExtendObject: [
|
|
o("EXTEND Identifier ClassBody", function() {
|
|
return new ExtendDeclaration(A2, null, A3).set({ instanceOnly: true, extension: A1 });
|
|
})
|
|
],
|
|
ExportDeclaration: [
|
|
o("EXPORT { ImportSpecifierList }", function() {
|
|
return new ExportNamedDeclaration(A1, [A3]);
|
|
}),
|
|
o("EXPORT { ImportSpecifierList } FROM String", function() {
|
|
return new ExportNamedDeclaration(A1, [A3], A6);
|
|
}),
|
|
o("EXPORT EXPORT_ALL FROM String", function() {
|
|
return new ExportAllDeclaration(A1, [new ExportAllSpecifier(A2)], A4);
|
|
}),
|
|
o("EXPORT EXPORT_ALL AS Identifier FROM String", function() {
|
|
return new ExportAllDeclaration(A1, [new ExportAllSpecifier(A2, A4)], A6);
|
|
}),
|
|
o("EXPORT Exportable", function() {
|
|
return new Export(A2).set({ keyword: A1 });
|
|
}),
|
|
o("EXPORT DEFAULT DefaultExportable", function() {
|
|
return new Export(A3).set({ keyword: A1, "default": A2 });
|
|
})
|
|
],
|
|
Exportable: [
|
|
o("MethodDeclaration"),
|
|
o("Class"),
|
|
o("CSSDeclaration"),
|
|
o("TagDeclaration"),
|
|
o("VarAssign")
|
|
],
|
|
DefaultExportable: [
|
|
o("Expression")
|
|
],
|
|
ImportOrExport: [
|
|
o("IMPORT"),
|
|
o("EXPORT")
|
|
],
|
|
ImportDefaultSpecifier: [
|
|
o("Identifier", function() {
|
|
return new ImportDefaultSpecifier(A1);
|
|
})
|
|
],
|
|
ImportDeclaration: [
|
|
o("IMPORT String", function() {
|
|
return new ImportDeclaration(A1, null, A2);
|
|
}),
|
|
o("IMPORT ImportDefaultSpecifier FROM String", function() {
|
|
return new ImportDeclaration(A1, [A2], A4);
|
|
}),
|
|
o("IMPORT TYPEIMPORT ImportDefaultSpecifier FROM String", function() {
|
|
return new ImportTypeDeclaration(A1, [A3], A5);
|
|
}),
|
|
o("IMPORT ImportNamespaceSpecifier FROM String", function() {
|
|
return new ImportDeclaration(A1, [A2], A4);
|
|
}),
|
|
o("IMPORT { } FROM String", function() {
|
|
return new ImportDeclaration(A1, null, A5);
|
|
}),
|
|
o("IMPORT { ImportSpecifierList } FROM String", function() {
|
|
return new ImportDeclaration(A1, [A3], A6);
|
|
}),
|
|
o("IMPORT TYPEIMPORT { ImportSpecifierList } FROM String", function() {
|
|
return new ImportTypeDeclaration(A1, [A4], A7);
|
|
}),
|
|
o("IMPORT ImportDefaultSpecifier IMPORT_COMMA ImportNamespaceSpecifier FROM String", function() {
|
|
return new ImportDeclaration(A1, [A2, A4], A6);
|
|
}),
|
|
o("IMPORT ImportDefaultSpecifier IMPORT_COMMA { ImportSpecifierList } FROM String", function() {
|
|
return new ImportDeclaration(A1, [A2, A5], A8);
|
|
})
|
|
],
|
|
ImportFrom: [
|
|
o("STRING")
|
|
],
|
|
ImportNamespaceSpecifier: [
|
|
o("IMPORT_ALL AS Identifier", function() {
|
|
return new ImportNamespaceSpecifier(new Literal(A1), A3);
|
|
})
|
|
],
|
|
ImportSpecifierList: [
|
|
o("ImportSpecifier", function() {
|
|
return new ESMSpecifierList([]).add(A1);
|
|
}),
|
|
o("ImportSpecifierList , ImportSpecifier", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("ImportSpecifierList OptComma TERMINATOR ImportSpecifier", function() {
|
|
return A1.add(A4);
|
|
}),
|
|
o("INDENT ImportSpecifierList OptComma OUTDENT", function() {
|
|
return A2;
|
|
}),
|
|
o("INDENT ImportSpecifierList OptComma TERMINATOR OUTDENT", function() {
|
|
return A2;
|
|
}),
|
|
o("ImportSpecifierList OptComma INDENT ImportSpecifierList OptComma OUTDENT", function() {
|
|
return A1.concat(A4);
|
|
})
|
|
],
|
|
ImportSpecifier: [
|
|
o("Identifier", function() {
|
|
return new ImportSpecifier(A1);
|
|
}),
|
|
o("DecoratorIdentifier", function() {
|
|
return new ImportSpecifier(A1);
|
|
}),
|
|
o("MixinIdentifier", function() {
|
|
return new ImportSpecifier(A1);
|
|
}),
|
|
o("Identifier AS Identifier", function() {
|
|
return new ImportSpecifier(A1, A3);
|
|
}),
|
|
o("DEFAULT", function() {
|
|
return new ImportSpecifier(new Literal(A1));
|
|
}),
|
|
o("DEFAULT AS Identifier", function() {
|
|
return new ImportSpecifier(new Literal(A1), A3);
|
|
})
|
|
],
|
|
Require: [
|
|
o("REQUIRE RequireArg", function() {
|
|
return new Require(A2).set({ keyword: A1 });
|
|
})
|
|
],
|
|
RequireArg: [
|
|
o("Literal"),
|
|
o("Parenthetical"),
|
|
o("")
|
|
],
|
|
Expression: [
|
|
o("Await"),
|
|
o("Value"),
|
|
o("Code"),
|
|
o("Operation"),
|
|
o("Assign"),
|
|
o("If"),
|
|
o("Ternary"),
|
|
o("Try"),
|
|
o("While"),
|
|
o("For"),
|
|
o("Switch"),
|
|
o("ExtendObject"),
|
|
o("Class"),
|
|
o("TagDeclaration"),
|
|
o("Tag")
|
|
],
|
|
ExpressionBlock: [
|
|
o("Expression"),
|
|
o("INDENT ExpressionBlock Outdent", function() {
|
|
return A2.indented(A1, A3);
|
|
})
|
|
],
|
|
Identifier: [
|
|
o("IDENTIFIER", function() {
|
|
return new Identifier(A1);
|
|
})
|
|
],
|
|
SymbolIdentifier: [
|
|
o("SYMBOLID", function() {
|
|
return new SymbolIdentifier(A1);
|
|
})
|
|
],
|
|
DecoratorIdentifier: [
|
|
o("DECORATOR", function() {
|
|
return new DecoratorIdentifier(A1);
|
|
})
|
|
],
|
|
MixinIdentifier: [
|
|
o("MIXIN", function() {
|
|
return new MixinIdentifier(A1);
|
|
})
|
|
],
|
|
Key: [
|
|
o("KEY", function() {
|
|
return new Identifier(A1);
|
|
})
|
|
],
|
|
Argvar: [
|
|
o("ARGVAR", function() {
|
|
return new Argvar(A1);
|
|
})
|
|
],
|
|
Symbol: [
|
|
o("SYMBOL", function() {
|
|
return new Symbol(A1);
|
|
})
|
|
],
|
|
Decorator: [
|
|
o("DecoratorIdentifier", function() {
|
|
return new Decorator(A1);
|
|
}),
|
|
o("DecoratorIdentifier Arguments", function() {
|
|
return new Decorator(A1).set({ params: A2 });
|
|
}),
|
|
o("Decorator . Identifier", function() {
|
|
return A1.add(A3);
|
|
})
|
|
],
|
|
Decorators: [
|
|
o("Decorator", function() {
|
|
return [A1];
|
|
}),
|
|
o("Decorators Decorator", function() {
|
|
return A1.concat(A2);
|
|
})
|
|
],
|
|
AlphaNumeric: [
|
|
o("NUMBER UNIT", function() {
|
|
return new NumWithUnit(A1, A2);
|
|
}),
|
|
o("NUMBER", function() {
|
|
return new Num(A1);
|
|
}),
|
|
o("STRING", function() {
|
|
return new Str(A1);
|
|
}),
|
|
o("Symbol"),
|
|
o("InterpolatedString")
|
|
],
|
|
String: [
|
|
o("STRING", function() {
|
|
return new Str(A1);
|
|
})
|
|
],
|
|
InterpolatedString: [
|
|
o("STRING_START", function() {
|
|
return new InterpolatedString([], { open: A1 });
|
|
}),
|
|
o("InterpolatedString NEOSTRING", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("InterpolatedString Interpolation", function() {
|
|
return A2 ? A1.add(A2) : A1;
|
|
}),
|
|
o("InterpolatedString STRING_END", function() {
|
|
return A1.option("close", A2);
|
|
})
|
|
],
|
|
Interpolation: [
|
|
o("{{ }}", function() {
|
|
return null;
|
|
}),
|
|
o("{{ Expression }}", function() {
|
|
return A2;
|
|
})
|
|
],
|
|
Literal: [
|
|
o("AlphaNumeric"),
|
|
o("JS", function() {
|
|
return new Literal(A1);
|
|
}),
|
|
o("REGEX", function() {
|
|
return new RegExp(A1);
|
|
}),
|
|
o("BOOL", function() {
|
|
return new Bool(A1);
|
|
}),
|
|
o("TRUE", function() {
|
|
return new True(A1);
|
|
}),
|
|
o("FALSE", function() {
|
|
return new False(A1);
|
|
}),
|
|
o("NULL", function() {
|
|
return new Nil(A1);
|
|
}),
|
|
o("UNDEFINED", function() {
|
|
return new Undefined(A1);
|
|
})
|
|
],
|
|
Return: [
|
|
o("RETURN Expression", function() {
|
|
return new Return(A2).set({ keyword: A1 });
|
|
}),
|
|
o("RETURN Arguments", function() {
|
|
return new Return(A2).set({ keyword: A1 });
|
|
}),
|
|
o("RETURN", function() {
|
|
return new Return().set({ keyword: A1 });
|
|
})
|
|
],
|
|
Selector: [
|
|
o("SELECTOR_START", function() {
|
|
return new Selector([], { type: A1, open: A1 });
|
|
}),
|
|
o("Selector SELECTOR_PART", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("Selector { Expression }", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("Selector SELECTOR_END", function() {
|
|
return A1.option("close", A2);
|
|
})
|
|
],
|
|
Tag: [
|
|
o("TAG_START TagOptions TAG_END", function() {
|
|
return A2.set({ open: A1, close: A3 });
|
|
}),
|
|
o("TAG_START TagOptions TAG_END TagBody", function() {
|
|
return A2.set({ body: A4, open: A1, close: A3 });
|
|
})
|
|
],
|
|
TagTypeName: [
|
|
o("Self", function() {
|
|
return A1;
|
|
}),
|
|
o("IDENTIFIER", function() {
|
|
return new TagTypeIdentifier(A1);
|
|
}),
|
|
o("TAG_TYPE", function() {
|
|
return new TagTypeIdentifier(A1);
|
|
}),
|
|
o("TagIdentifier", function() {
|
|
return new ExpressionNode(A1);
|
|
}),
|
|
o("", function() {
|
|
return new TagTypeIdentifier("div");
|
|
})
|
|
],
|
|
StyleBlockDeclaration: [
|
|
o("CSS CSS_SEL StyleBody CSS_END", function() {
|
|
return new StyleRuleSet(A2, A3).set({ name: A1 });
|
|
})
|
|
],
|
|
CSSDeclaration: [
|
|
o("StyleBlockDeclaration", function() {
|
|
return A1.set({ toplevel: true });
|
|
}),
|
|
o("GLOBAL CSSDeclaration", function() {
|
|
return A2.set({ global: A1 });
|
|
}),
|
|
o("LOCAL CSSDeclaration", function() {
|
|
return A2.set({ local: A1 });
|
|
})
|
|
],
|
|
StyleBlockBody: [
|
|
o("INDENT Terminator OUTDENT", function() {
|
|
return new StyleBody([]).indented(A1, A3);
|
|
}),
|
|
o("INDENT StyleBody Outdent", function() {
|
|
return A2.indented(A1, A3);
|
|
})
|
|
],
|
|
OptStyleBody: [
|
|
o("", function() {
|
|
return new StyleBody([]);
|
|
}),
|
|
o("StyleBody")
|
|
],
|
|
StyleBody: [
|
|
o("StyleNode", function() {
|
|
return new StyleBody([A1]);
|
|
}),
|
|
o("StyleBody StyleDeclaration", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("StyleBody Terminator StyleNode", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("INDENT StyleBody Outdent", function() {
|
|
return A2.indented(A1, A3);
|
|
})
|
|
],
|
|
StyleNode: [
|
|
o("StyleDeclaration"),
|
|
o("CSS_SEL StyleBlockBody CSS_END", function() {
|
|
return new StyleRuleSet(A1, A2);
|
|
})
|
|
],
|
|
StyleDeclaration: [
|
|
o("StyleProperty : StyleExpressions", function() {
|
|
return new StyleDeclaration(A1, A3.set({ parens: false }));
|
|
}),
|
|
o("StyleProperty = StyleExpressions", function() {
|
|
return new StyleDeclaration(A1, A3.set({ parens: false }));
|
|
})
|
|
],
|
|
StyleProperty: [
|
|
o("CSSPROP", function() {
|
|
return new StyleProperty([A1]);
|
|
})
|
|
],
|
|
StyleOperator: [
|
|
o("MATH"),
|
|
o("+"),
|
|
o("-")
|
|
],
|
|
StyleExpressions: [
|
|
o("StyleExpression", function() {
|
|
return new StyleExpressions([A1]);
|
|
}),
|
|
o("StyleExpressions , StyleExpression", function() {
|
|
return A1.add(A3);
|
|
})
|
|
],
|
|
StyleExpression: [
|
|
o("StyleTerm", function() {
|
|
return new StyleExpression().add(A1);
|
|
}),
|
|
o("StyleExpression StyleOperator", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("StyleExpression StyleTerm", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("StyleExpression / StyleTerm", function() {
|
|
return A1.addParam(A3, A2);
|
|
})
|
|
],
|
|
StyleValue: [
|
|
o("StyleTerm"),
|
|
o("StyleOperation")
|
|
],
|
|
StyleOperation: [
|
|
o("StyleTerm StyleOperator StyleTerm", function() {
|
|
return new StyleOperation([A1, A2, A3]);
|
|
}),
|
|
o("StyleOperation StyleOperator StyleTerm", function() {
|
|
return A1.add([A2, A3]);
|
|
})
|
|
],
|
|
StyleFunctionArgs: [
|
|
o("StyleFunctionArg", function() {
|
|
return new StyleExpressions([A1]);
|
|
}),
|
|
o("StyleFunctionArgs , StyleFunctionArg", function() {
|
|
return A1.add(A3);
|
|
})
|
|
],
|
|
StyleFunctionArg: [
|
|
o("StyleTerm", function() {
|
|
return new StyleExpression().add(A1);
|
|
}),
|
|
o("StyleFunctionArg StyleOperator", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("StyleFunctionArg StyleTerm", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("StyleFunctionArg / StyleTerm", function() {
|
|
return A1.addParam(A3, A2);
|
|
})
|
|
],
|
|
StyleTermPlaceholder: [
|
|
o("{ Expression }", function() {
|
|
return new StyleInterpolationExpression(A2).setEnds(A1, A3);
|
|
}),
|
|
o("StyleTermPlaceholder CSSUNIT", function() {
|
|
return A1.set({ unit: A2 });
|
|
})
|
|
],
|
|
StyleParens: [
|
|
o("( StyleValue )", function() {
|
|
return new StyleParens(A2).setEnds(A1, A3);
|
|
}),
|
|
o("StyleParens CSSUNIT", function() {
|
|
return A1.set({ unit: A2 });
|
|
})
|
|
],
|
|
StyleTerm: [
|
|
o("StyleParens"),
|
|
o("CSSVAR", function() {
|
|
return new StyleVar(A1);
|
|
}),
|
|
o("DIMENSION", function() {
|
|
return new StyleDimension(A1);
|
|
}),
|
|
o("COLOR", function() {
|
|
return new StyleColor(A1);
|
|
}),
|
|
o("PERCENTAGE", function() {
|
|
return new StyleDimension(A1);
|
|
}),
|
|
o("NUMBER", function() {
|
|
return new StyleNumber(A1);
|
|
}),
|
|
o("String", function() {
|
|
return A1;
|
|
}),
|
|
o("StyleTermPlaceholder", function() {
|
|
return A1;
|
|
}),
|
|
o("CSSURL", function() {
|
|
return new StyleURL(A1);
|
|
}),
|
|
o("CSSFUNCTION ( StyleFunctionArgs )", function() {
|
|
return new StyleFunction(A1, A3);
|
|
}),
|
|
o("CSSIDENTIFIER", function() {
|
|
return new StyleIdentifier(A1);
|
|
}),
|
|
o("COMPARE StyleTerm", function() {
|
|
return A2.set({ op: A1 });
|
|
})
|
|
],
|
|
TagOptions: [
|
|
o("TagTypeName TAG_REF", function() {
|
|
return new Tag({ type: A1, reference: A2 });
|
|
}),
|
|
o("TagTypeName", function() {
|
|
return new Tag({ type: A1 });
|
|
}),
|
|
o("TagOptions TAG_ID", function() {
|
|
return A1.addPart(A2, AST.TagId);
|
|
}),
|
|
o("TagOptions TAG_SYMBOL_ID", function() {
|
|
return A1.addPart(new IdentifierExpression(A2.cloneSlice(1)), AST.TagId);
|
|
}),
|
|
o("TagOptions SYMBOL_ID", function() {
|
|
return A1.addPart(new IdentifierExpression(A2.cloneSlice(1)), AST.TagId);
|
|
}),
|
|
o("TagOptions TAG_FLAG", function() {
|
|
return A1.addPart(A2, AST.TagFlag);
|
|
}),
|
|
o("TagOptions TAG_ATTR", function() {
|
|
return A1.addPart(A2, AST.TagAttr);
|
|
}),
|
|
o("TagOptions STYLE_START STYLE_END", function() {
|
|
return A1;
|
|
}),
|
|
o("TagOptions STYLE_START StyleBody STYLE_END", function() {
|
|
return A1.addPart(new StyleRuleSet(null, A3), AST.TagFlag);
|
|
}),
|
|
o("TagOptions T. STYLE_START StyleBody STYLE_END", function() {
|
|
return A1.addPart(new StyleRuleSet(null, A4), AST.TagFlag);
|
|
}),
|
|
o("TagOptions MIXIN", function() {
|
|
return A1.addPart(new MixinIdentifier(A2), AST.TagFlag);
|
|
}),
|
|
o("TagOptions T: TagIdentifier", function() {
|
|
return A1.addPart(A3, AST.TagHandler);
|
|
}),
|
|
o("TagOptions T@ TagIdentifier", function() {
|
|
return A1.addPart(A3, AST.TagHandler);
|
|
}),
|
|
o("TagOptions T. @ TAG_LITERAL", function() {
|
|
return A1.addPart(A4.prepend("_"), AST.TagFlag);
|
|
}),
|
|
o("TagOptions T. UNARY TAG_LITERAL", function() {
|
|
return A1.addPart(A4.prepend("!"), AST.TagFlag);
|
|
}),
|
|
o("TagOptions T. TagIdentifier", function() {
|
|
return A1.addPart(A3, AST.TagFlag);
|
|
}),
|
|
o("TagOptions # TagIdentifier", function() {
|
|
return A1.addPart(A3, AST.TagId);
|
|
}),
|
|
o("TagOptions TAG_WS TagIdentifier", function() {
|
|
return A1.addPart(A2, AST.TagSep).addPart(A3, AST.TagAttr);
|
|
}),
|
|
o("TagOptions ( )", function() {
|
|
return A1.addPart(new ArgList([]), AST.TagArgList);
|
|
}),
|
|
o("TagOptions ( ArgList )", function() {
|
|
return A1.addPart(A3, AST.TagArgList);
|
|
}),
|
|
o("TagOptions CALL_START CALL_END", function() {
|
|
return A1.addPart(null, AST.TagArgList);
|
|
}),
|
|
o("TagOptions CALL_START ArgList CALL_END", function() {
|
|
return A1.addPart(A3, AST.TagArgList);
|
|
}),
|
|
o("TagOptions TAG_WS", function() {
|
|
return A1.addPart(A2, AST.TagSep);
|
|
}),
|
|
o("TagOptions Comment", function() {
|
|
return A1;
|
|
}),
|
|
o("TagOptions TERMINATOR", function() {
|
|
return A1;
|
|
}),
|
|
o("TagOptions = TagAttrValue", function() {
|
|
return A1.addPart(A3, AST.TagAttrValue, A2);
|
|
})
|
|
],
|
|
TagIdentifier: [
|
|
o("TAG_LITERAL", function() {
|
|
return new IdentifierExpression(A1);
|
|
}),
|
|
o("{ Expression }", function() {
|
|
return new IdentifierExpression(A2);
|
|
}),
|
|
o("TagIdentifier TAG_LITERAL", function() {
|
|
return A1.add(A2);
|
|
}),
|
|
o("TagIdentifier { Expression }", function() {
|
|
return A1.add(A3);
|
|
})
|
|
],
|
|
TagFlag: [
|
|
o("%", function() {
|
|
return new TagFlag();
|
|
}),
|
|
o("TagFlag TagPartIdentifier", function() {
|
|
return A1.add(A2);
|
|
})
|
|
],
|
|
TagAttrValue: [
|
|
o("VALUE_START Expression VALUE_END", function() {
|
|
return A2;
|
|
})
|
|
],
|
|
TagBody: [
|
|
o("INDENT OUTDENT", function() {
|
|
return new TagBody([]).indented(A1, A2);
|
|
}),
|
|
o("INDENT TagBodyList OUTDENT", function() {
|
|
return A2.indented(A1, A3);
|
|
}),
|
|
o("CALL_START TagBodyList CALL_END", function() {
|
|
return A2;
|
|
}),
|
|
o("Tag", function() {
|
|
return new TagBody([A1]);
|
|
})
|
|
],
|
|
TagBodyList: [
|
|
o("TagBodyItem", function() {
|
|
return new TagBody([]).add(A1);
|
|
}),
|
|
o("TagBodyList , TagBodyItem", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("TagBodyList OptComma Terminator TagBodyItem", function() {
|
|
return A1.add(A3).add(A4);
|
|
}),
|
|
o("TagBodyList OptComma TERMINATOR SEPARATOR Terminator TagBodyItem", function() {
|
|
return A1.add(A5).add(A6);
|
|
}),
|
|
o("INDENT TagBodyList OptComma Outdent", function() {
|
|
return A2.indented(A1, A4);
|
|
}),
|
|
o("TagBodyList OptComma INDENT TagBodyList OptComma Outdent", function() {
|
|
return A1.concat(A4);
|
|
})
|
|
],
|
|
TagBodyItem: [
|
|
o("Expression"),
|
|
o("... Expression", function() {
|
|
return new Splat(A2).set({ keyword: A1 });
|
|
}),
|
|
o("Splat"),
|
|
o("LOGIC"),
|
|
o("Comment"),
|
|
o("StyleBlockDeclaration", function() {
|
|
return A1.set({ inTagTree: true });
|
|
})
|
|
],
|
|
TagDeclaration: [
|
|
o("TagDeclarationBlock", function() {
|
|
return A1;
|
|
}),
|
|
o("EXTEND TagDeclarationBlock", function() {
|
|
return A2.set({ extension: true });
|
|
}),
|
|
o("LOCAL TagDeclarationBlock", function() {
|
|
return A2.set({ local: true });
|
|
}),
|
|
o("GLOBAL TagDeclarationBlock", function() {
|
|
return A2.set({ global: A1 });
|
|
})
|
|
],
|
|
TagDeclarationBlock: [
|
|
o("TAG TagType", function() {
|
|
return new TagDeclaration(A2).set({ keyword: A1 });
|
|
}),
|
|
o("TAG TagType ClassBody", function() {
|
|
return new TagDeclaration(A2, null, A3).set({ keyword: A1 });
|
|
}),
|
|
o("TAG TagType COMPARE TagType", function() {
|
|
return new TagDeclaration(A2, A4).set({ keyword: A1 });
|
|
}),
|
|
o("TAG TagType COMPARE TagType ClassBody", function() {
|
|
return new TagDeclaration(A2, A4, A5).set({ keyword: A1 });
|
|
})
|
|
],
|
|
TagType: [
|
|
o("TAG_TYPE", function() {
|
|
return new TagTypeIdentifier(A1);
|
|
})
|
|
],
|
|
TagId: [
|
|
o("# IDENTIFIER", function() {
|
|
return new TagIdRef(A2);
|
|
})
|
|
],
|
|
Assign: [
|
|
o("VarAssign"),
|
|
o("Assignable = Expression", function() {
|
|
return new Assign(A2, A1, A3);
|
|
}),
|
|
o("Assignable = INDENT Expression Outdent", function() {
|
|
return new Assign(A2, A1, A4.indented(A3, A5));
|
|
})
|
|
],
|
|
AssignObj: [
|
|
o("... Expression", function() {
|
|
return new ObjRestAttr(A2).set({ spread: A1 });
|
|
}),
|
|
o("MethodDeclaration", function() {
|
|
return A1.set({ inObject: true });
|
|
}),
|
|
o("ObjAssignable", function() {
|
|
return new ObjAttr(A1);
|
|
}),
|
|
o("ObjAssignable : Expression", function() {
|
|
return new ObjAttr(A1, A3);
|
|
}),
|
|
o("ObjAssignable : INDENT Expression Outdent", function() {
|
|
return new ObjAttr(A1, A4.indented(A3, A5));
|
|
}),
|
|
o("SimpleObjAssignable = Expression", function() {
|
|
return new ObjAttr(A1, null, A3);
|
|
}),
|
|
o("SimpleObjAssignable = INDENT Expression Outdent", function() {
|
|
return new ObjAttr(A1, null, A4.indented(A3, A5));
|
|
}),
|
|
o("Comment")
|
|
],
|
|
SimpleObjAssignable: [
|
|
o("Identifier"),
|
|
o("Identifier Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
}),
|
|
o("SymbolIdentifier"),
|
|
o("Key")
|
|
],
|
|
ObjAssignable: [
|
|
o("SimpleObjAssignable"),
|
|
o("[ Expression ]", function() {
|
|
return new IdentifierExpression(A2);
|
|
}),
|
|
o("( Expression )", function() {
|
|
return new IdentifierExpression(A2);
|
|
}),
|
|
o("AlphaNumeric")
|
|
],
|
|
Comment: [
|
|
o("HERECOMMENT", function() {
|
|
return new Comment(A1, true);
|
|
}),
|
|
o("COMMENT", function() {
|
|
return new Comment(A1, false);
|
|
})
|
|
],
|
|
Code: [
|
|
o("Method"),
|
|
o("Do"),
|
|
o("Begin")
|
|
],
|
|
Begin: [
|
|
o("BEGIN Block", function() {
|
|
return new Begin(A2);
|
|
})
|
|
],
|
|
Do: [
|
|
o("DO Block", function() {
|
|
return new Lambda([], A2, null, null, { bound: true, keyword: A1 });
|
|
}),
|
|
o("DO BLOCK_PARAM_START ParamList BLOCK_PARAM_END Block", function() {
|
|
return new Lambda(A3, A5, null, null, { bound: true, keyword: A1 });
|
|
})
|
|
],
|
|
Method: [
|
|
o("MethodDeclaration", function() {
|
|
return A1;
|
|
}),
|
|
o("GLOBAL MethodDeclaration", function() {
|
|
return A2.set({ global: A1 });
|
|
}),
|
|
o("STATIC MethodDeclaration", function() {
|
|
return A2.set({ static: A1 });
|
|
})
|
|
],
|
|
MethodDeclaration: [
|
|
o("DEF MethodScope MethodScopeType MethodIdentifier MethodParams MethodBody", function() {
|
|
return new MethodDeclaration(A5, A6, A4, A2, A3).set({ def: A1, keyword: A1, datatype: A4.option("datatype") });
|
|
}),
|
|
o("DEF MethodIdentifier MethodParams MethodBody", function() {
|
|
return new MethodDeclaration(A3, A4, A2, null).set({ def: A1, keyword: A1, datatype: A2.option("datatype") });
|
|
})
|
|
],
|
|
MethodParams: [
|
|
o("ParamList", function() {
|
|
return A1;
|
|
}),
|
|
o("CALL_START ParamList CALL_END", function() {
|
|
return A2;
|
|
})
|
|
],
|
|
MethodScopeType: [
|
|
o(".", function() {
|
|
return { static: true };
|
|
}),
|
|
o("#", function() {
|
|
return {};
|
|
})
|
|
],
|
|
MethodIdentifier: [
|
|
o("Identifier"),
|
|
o("DecoratorIdentifier"),
|
|
o("SymbolIdentifier", function() {
|
|
return A1;
|
|
}),
|
|
o("[ Expression ]", function() {
|
|
return new InterpolatedIdentifier(A2);
|
|
}),
|
|
o("MethodIdentifier Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
})
|
|
],
|
|
MethodBody: [
|
|
o("DEF_BODY Block", function() {
|
|
return A2;
|
|
}),
|
|
o("DEF_BODY DO Block", function() {
|
|
return A3;
|
|
}),
|
|
o("DEF_EMPTY", function() {
|
|
return new Block([]).set({ end: A1._loc });
|
|
})
|
|
],
|
|
MethodScope: [
|
|
o("MethodIdentifier"),
|
|
o("This"),
|
|
o("Self")
|
|
],
|
|
OptComma: [
|
|
o(""),
|
|
o(",")
|
|
],
|
|
OptSemicolon: [
|
|
o(""),
|
|
o(";")
|
|
],
|
|
ParamList: [
|
|
o("", function() {
|
|
return [];
|
|
}),
|
|
o("Param", function() {
|
|
return [A1];
|
|
}),
|
|
o("ParamList , Param", function() {
|
|
return A1.concat(A3);
|
|
})
|
|
],
|
|
ParamExpression: [
|
|
o("Value"),
|
|
o("Code"),
|
|
o("Operation"),
|
|
o("Assign"),
|
|
o("Ternary"),
|
|
o("Tag")
|
|
],
|
|
ParamValue: [
|
|
o("Expression")
|
|
],
|
|
Param: [
|
|
o("Object", function() {
|
|
return new Param(A1);
|
|
}),
|
|
o("Array", function() {
|
|
return new Param(A1);
|
|
}),
|
|
o("ParamVar"),
|
|
o("... ParamVar", function() {
|
|
return A2.set({ splat: A1 });
|
|
}),
|
|
o("BLOCK_ARG ParamVar", function() {
|
|
return A2.set({ blk: A1 });
|
|
}),
|
|
o("ParamVar = ParamValue", function() {
|
|
return new Param(A1.value(), A3).set({ datatype: A1.option("datatype") });
|
|
}),
|
|
o("Object = ParamValue", function() {
|
|
return new Param(A1, A3);
|
|
}),
|
|
o("Array = ParamValue", function() {
|
|
return new Param(A1, A3);
|
|
}),
|
|
o("...", function() {
|
|
return new RestParam(A1);
|
|
})
|
|
],
|
|
ParamVar: [
|
|
o("Identifier", function() {
|
|
return new Param(A1);
|
|
}),
|
|
o("Identifier Type", function() {
|
|
return new Param(A1).set({ datatype: A2 });
|
|
})
|
|
],
|
|
Splat: [
|
|
o("SPLAT Expression", function() {
|
|
return AST.SPLAT(A2);
|
|
})
|
|
],
|
|
VarKeyword: [
|
|
o("VAR"),
|
|
o("LET"),
|
|
o("CONST")
|
|
],
|
|
VarAssignable: [
|
|
o("Identifier"),
|
|
o("Identifier Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
}),
|
|
o("Array"),
|
|
o("Object")
|
|
],
|
|
VarDecl: [
|
|
o("VarKeyword VarAssignable", function() {
|
|
return new VarReference(A2, A1);
|
|
})
|
|
],
|
|
VarAssign: [
|
|
o("VarDecl = Expression", function() {
|
|
return new Assign(A2, A1, A3);
|
|
}),
|
|
o("VarDecl = INDENT Expression Outdent", function() {
|
|
return new Assign(A2, A1, A4.indented(A3, A5));
|
|
})
|
|
],
|
|
SimpleAssignable: [
|
|
o("ENV_FLAG", function() {
|
|
return new EnvFlag(A1);
|
|
}),
|
|
o("Argvar"),
|
|
o("Self"),
|
|
o("Identifier", function() {
|
|
return new VarOrAccess(A1);
|
|
}),
|
|
o("SymbolIdentifier", function() {
|
|
return new Access(".", null, A1);
|
|
}),
|
|
o("Access"),
|
|
o("SimpleAssignable Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
})
|
|
],
|
|
Access: [
|
|
o("Value SoakableOp Identifier", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("Value SoakableOp SymbolIdentifier", function() {
|
|
return new IndexAccess(A2, A1, A3);
|
|
}),
|
|
o("Value INDEX_START IndexValue INDEX_END", function() {
|
|
return new IndexAccess(".", A1, A3);
|
|
}),
|
|
o("Value ?. [ IndexValue ]", function() {
|
|
return AST.OP(A2, A1, A4);
|
|
})
|
|
],
|
|
SoakableOp: [
|
|
".",
|
|
"?."
|
|
],
|
|
Super: [
|
|
o("SUPER", function() {
|
|
return new Super(A1);
|
|
})
|
|
],
|
|
Assignable: [
|
|
o("SimpleAssignable"),
|
|
o("Array"),
|
|
o("Object")
|
|
],
|
|
TaggedTemplate: [
|
|
o("SimpleAssignable InterpolatedString", function() {
|
|
return new TaggedTemplate(A1, A2);
|
|
}),
|
|
o("SimpleAssignable String", function() {
|
|
return new TaggedTemplate(A1, A2);
|
|
})
|
|
],
|
|
Await: [
|
|
o("AWAIT Expression", function() {
|
|
return new Await(A2).set({ keyword: A1 });
|
|
})
|
|
],
|
|
Value: [
|
|
o("Assignable"),
|
|
o("Super"),
|
|
o("Literal"),
|
|
o("Parenthetical"),
|
|
o("Range"),
|
|
o("ARGUMENTS", function() {
|
|
return AST.ARGUMENTS;
|
|
}),
|
|
o("This"),
|
|
o("TagId"),
|
|
o("Selector"),
|
|
o("Invocation"),
|
|
o("TaggedTemplate"),
|
|
o("Require"),
|
|
o("Value BANG", function() {
|
|
return new BangCall(A1).set({ keyword: A2 });
|
|
})
|
|
],
|
|
IndexValue: [
|
|
o("Expression", function() {
|
|
return new Index(A1);
|
|
})
|
|
],
|
|
Object: [
|
|
o("{ AssignList OptComma }", function() {
|
|
return new Obj(A2, A1.generated).setEnds(A1, A4);
|
|
})
|
|
],
|
|
AssignList: [
|
|
o("", function() {
|
|
return new AssignList([]);
|
|
}),
|
|
o("AssignObj", function() {
|
|
return new AssignList([A1]);
|
|
}),
|
|
o("AssignList , AssignObj", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("AssignList OptComma Terminator AssignObj", function() {
|
|
return A1.add(A3).add(A4);
|
|
}),
|
|
o("AssignList OptComma INDENT AssignList OptComma Outdent", function() {
|
|
return A1.concat(A4.indented(A3, A6));
|
|
})
|
|
],
|
|
ExpressionList: [
|
|
o("Expression", function() {
|
|
return new ExpressionList([]).add(A1);
|
|
}),
|
|
o("ExpressionList , Expression", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("ExpressionList OptComma Terminator Expression", function() {
|
|
return A1.add(A3).add(A4);
|
|
}),
|
|
o("INDENT ExpressionList OptComma Outdent", function() {
|
|
return A2.indented(A1, A4);
|
|
}),
|
|
o("ExpressionList OptComma INDENT ExpressionList OptComma Outdent", function() {
|
|
return A1.concat(A4);
|
|
})
|
|
],
|
|
Class: [
|
|
o("ClassStart", function() {
|
|
return A1;
|
|
}),
|
|
o("EXTEND ClassStart", function() {
|
|
return A2.set({ extension: A1 });
|
|
}),
|
|
o("LOCAL ClassStart", function() {
|
|
return A2.set({ local: A1 });
|
|
}),
|
|
o("GLOBAL ClassStart", function() {
|
|
return A2.set({ global: A1 });
|
|
})
|
|
],
|
|
ClassStart: [
|
|
o("CLASS ClassName ClassBody", function() {
|
|
return new ClassDeclaration(A2, null, A3).set({ keyword: A1 });
|
|
}),
|
|
o("CLASS ClassName", function() {
|
|
return new ClassDeclaration(A2, null, []).set({ keyword: A1 });
|
|
}),
|
|
o("CLASS ClassBody", function() {
|
|
return new ClassDeclaration(null, null, A2).set({ keyword: A1 });
|
|
}),
|
|
o("CLASS ClassName COMPARE Expression", function() {
|
|
return new ClassDeclaration(A2, A4, []).set({ keyword: A1 });
|
|
}),
|
|
o("CLASS ClassName COMPARE Expression ClassBody", function() {
|
|
return new ClassDeclaration(A2, A4, A5).set({ keyword: A1 });
|
|
}),
|
|
o("CLASS COMPARE Expression ClassBody", function() {
|
|
return new ClassDeclaration(null, A3, A4).set({ keyword: A1 });
|
|
})
|
|
],
|
|
ClassName: [
|
|
o("DecoratorIdentifier"),
|
|
o("Identifier", function() {
|
|
return new VarOrAccess(A1);
|
|
}),
|
|
o("SymbolIdentifier", function() {
|
|
return new Access(".", null, A1);
|
|
}),
|
|
o("ClassName . Identifier", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("ClassName . SymbolIdentifier", function() {
|
|
return new IndexAccess(A2, A1, A3);
|
|
})
|
|
],
|
|
ClassBody: [
|
|
o("INDENT OUTDENT", function() {
|
|
return new ClassBody([]).indented(A1, A2);
|
|
}),
|
|
o("INDENT ClassBodyBlock OUTDENT", function() {
|
|
return A2.indented(A1, A3);
|
|
}),
|
|
o("INDENT TERMINATOR ClassBodyBlock OUTDENT", function() {
|
|
return A3.prebreak(A2).indented(A1, A4);
|
|
})
|
|
],
|
|
ClassBodyBlock: [
|
|
o("ClassBodyLine", function() {
|
|
return new ClassBody([]).add(A1);
|
|
}),
|
|
o("ClassBodyBlock Terminator ClassBodyLine", function() {
|
|
return A1.break(A2).add(A3);
|
|
}),
|
|
o("ClassBodyBlock Terminator", function() {
|
|
return A1.break(A2);
|
|
})
|
|
],
|
|
ClassBodyLine: [
|
|
o("Decorators"),
|
|
o("ClassDeclLine"),
|
|
o("Decorators ClassDeclLine", function() {
|
|
return A1.concat([A2]);
|
|
}),
|
|
o("CSSDeclaration"),
|
|
o("Comment"),
|
|
o("Tag")
|
|
],
|
|
ClassDeclLine: [
|
|
o("STATIC ClassFieldDeclaration", function() {
|
|
return A2.set({ static: A1 });
|
|
}),
|
|
o("DECLARE STATIC ClassFieldDeclaration", function() {
|
|
return A3.set({ static: A2, declareOnly: A1 });
|
|
}),
|
|
o("DECLARE ClassFieldDeclaration", function() {
|
|
return A2.set({ declareOnly: A1 });
|
|
}),
|
|
o("STATIC MethodDeclaration", function() {
|
|
return A2.set({ static: A1 });
|
|
}),
|
|
o("DECLARE MethodDeclaration", function() {
|
|
return A2.set({ declareOnly: A1 });
|
|
}),
|
|
o("DECLARE STATIC MethodDeclaration", function() {
|
|
return A2.set({ static: A2, declareOnly: A1 });
|
|
}),
|
|
o("MethodDeclaration"),
|
|
o("ClassFieldDeclaration")
|
|
],
|
|
ClassFieldDeclaration: [
|
|
o("ClassField ClassFieldOp Expression", function() {
|
|
return A1.set({ value: A3, op: A2 });
|
|
}),
|
|
o("ClassField", function() {
|
|
return A1;
|
|
}),
|
|
o("ClassFieldDeclaration AS AccessorBody", function() {
|
|
return A1.set({ wrapper: A3 });
|
|
}),
|
|
o("ClassFieldDeclaration FieldDescriptorFull", function() {
|
|
return A1.set({ wrapper: A2 });
|
|
})
|
|
],
|
|
FieldDescriptor: [
|
|
o("DECORATOR", function() {
|
|
return new Descriptor(A1);
|
|
}),
|
|
o("@ CALL_START Expression CALL_END", function() {
|
|
return new Descriptor(A3);
|
|
}),
|
|
o("FieldDescriptor Arguments", function() {
|
|
return A1.add(A2, "!");
|
|
}),
|
|
o("FieldDescriptor INDEX_START ArgList INDEX_END", function() {
|
|
return A1.add(A3, "=");
|
|
}),
|
|
o("FieldDescriptor . Identifier", function() {
|
|
return A1.add(A3);
|
|
})
|
|
],
|
|
FieldDescriptorFull: [
|
|
o("FieldDescriptor"),
|
|
o("FieldDescriptor = Expression", function() {
|
|
return A1.set({ "default": A3 });
|
|
}),
|
|
o("FieldDescriptor Do", function() {
|
|
return A1.set({ callback: A2 });
|
|
})
|
|
],
|
|
AccessorBody: [
|
|
"FieldDescriptorFull",
|
|
"Value"
|
|
],
|
|
ClassFieldDecoration: [
|
|
o("ClassFieldDeclaration @ WatchBody", function() {
|
|
return A1.set({ watch: A3 });
|
|
})
|
|
],
|
|
WatchBody: [
|
|
o("Block"),
|
|
o("Expression")
|
|
],
|
|
ClassFieldOp: [
|
|
"=",
|
|
"COMPOUND_ASSIGN"
|
|
],
|
|
ClassField: [
|
|
o("ClassFieldIdentifier", function() {
|
|
return new ClassField(A1);
|
|
}),
|
|
o("PROP ClassFieldIdentifier", function() {
|
|
return new ClassProperty(A2).set({ keyword: A1 });
|
|
}),
|
|
o("ATTR ClassFieldIdentifier", function() {
|
|
return new ClassAttribute(A2).set({ keyword: A1 });
|
|
}),
|
|
o("ClassField Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
}),
|
|
o("ClassField CALL_START CALL_END", function() {
|
|
return A1.set({ controller: A2 });
|
|
})
|
|
],
|
|
ClassFieldIdentifier: [
|
|
o("Identifier"),
|
|
o("SymbolIdentifier")
|
|
],
|
|
ClassFieldBody: [
|
|
o("WATCH Expression Terminator", function() {
|
|
return [A1, A2];
|
|
})
|
|
],
|
|
Invocation: [
|
|
o("Value OptFuncExist Arguments", function() {
|
|
return new Call(A1, A3, A2);
|
|
}),
|
|
o("Value Do", function() {
|
|
return A1.addBlock(A2);
|
|
})
|
|
],
|
|
OptFuncExist: [
|
|
o("", function() {
|
|
return false;
|
|
}),
|
|
o("FUNC_EXIST", function() {
|
|
return true;
|
|
})
|
|
],
|
|
Arguments: [
|
|
o("CALL_START CALL_END", function() {
|
|
return new ArgList([]).setEnds(A1, A2);
|
|
}),
|
|
o("CALL_START ArgList OptComma CALL_END", function() {
|
|
return A2.setEnds(A1, A4);
|
|
})
|
|
],
|
|
This: [
|
|
o("THIS", function() {
|
|
return new This(A1);
|
|
})
|
|
],
|
|
Self: [
|
|
o("SELF", function() {
|
|
return new Self(A1);
|
|
})
|
|
],
|
|
Array: [
|
|
o("[ ]", function() {
|
|
return new Arr(new ArgList([])).setEnds(A1, A2);
|
|
}),
|
|
o("[ ArgList OptComma ]", function() {
|
|
return new Arr(A2).setEnds(A1, A2);
|
|
}),
|
|
o("Array Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
})
|
|
],
|
|
RangeDots: [
|
|
o("..", function() {
|
|
return "..";
|
|
}),
|
|
o("...", function() {
|
|
return "...";
|
|
})
|
|
],
|
|
Range: [
|
|
o("[ Expression RangeDots Expression ]", function() {
|
|
return AST.OP(A3, A2, A4);
|
|
})
|
|
],
|
|
ArgList: [
|
|
o("Arg", function() {
|
|
return new ArgList([A1]);
|
|
}),
|
|
o("ArgList , Arg", function() {
|
|
return A1.add(A3);
|
|
}),
|
|
o("ArgList OptComma Terminator Arg", function() {
|
|
return A1.add(A3).add(A4);
|
|
}),
|
|
o("ArgList OptComma TERMINATOR SEPARATOR Terminator Arg", function() {
|
|
return A1.add(A5).add(A6);
|
|
}),
|
|
o("INDENT ArgList OptComma Outdent", function() {
|
|
return A2.indented(A1, A4);
|
|
}),
|
|
o("ArgList OptComma INDENT ArgList OptComma Outdent", function() {
|
|
return A1.concat(A4);
|
|
})
|
|
],
|
|
Outdent: [
|
|
o("Terminator OUTDENT", function() {
|
|
return A1;
|
|
}),
|
|
o("OUTDENT", function() {
|
|
return A1;
|
|
})
|
|
],
|
|
Arg: [
|
|
o("Expression"),
|
|
o("... Expression", function() {
|
|
return new Splat(A2).set({ keyword: A1 });
|
|
}),
|
|
o("Splat"),
|
|
o("DO_PLACEHOLDER", function() {
|
|
return new DoPlaceholder(A1);
|
|
}),
|
|
o("Comment")
|
|
],
|
|
SimpleArgs: [
|
|
o("Expression"),
|
|
o("SimpleArgs , Expression", function() {
|
|
return [].concat(A1, A3);
|
|
})
|
|
],
|
|
Try: [
|
|
o("TRY Block", function() {
|
|
return new Try(A2);
|
|
}),
|
|
o("TRY Block Catch", function() {
|
|
return new Try(A2, A3);
|
|
}),
|
|
o("TRY Block Finally", function() {
|
|
return new Try(A2, null, A3);
|
|
}),
|
|
o("TRY Block Catch Finally", function() {
|
|
return new Try(A2, A3, A4);
|
|
})
|
|
],
|
|
Finally: [
|
|
o("FINALLY Block", function() {
|
|
return new Finally(A2);
|
|
})
|
|
],
|
|
Catch: [
|
|
o("CATCH CATCH_VAR Block", function() {
|
|
return new Catch(A3, A2);
|
|
}),
|
|
o("CATCH Block", function() {
|
|
return new Catch(A2, null);
|
|
})
|
|
],
|
|
Throw: [
|
|
o("THROW Expression", function() {
|
|
return new Throw(A2);
|
|
})
|
|
],
|
|
Parenthetical: [
|
|
o("( ExpressionList )", function() {
|
|
return new Parens(A2, A1, A3);
|
|
}),
|
|
o("( ExpressionList ) UNIT", function() {
|
|
return new ExpressionWithUnit(new Parens(A2, A1, A3), A4);
|
|
}),
|
|
o("Parenthetical Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
})
|
|
],
|
|
WhileSource: [
|
|
o("WHILE Expression", function() {
|
|
return new While(A2, { keyword: A1 });
|
|
}),
|
|
o("WHILE Expression WHEN Expression", function() {
|
|
return new While(A2, { guard: A4, keyword: A1 });
|
|
}),
|
|
o("UNTIL Expression", function() {
|
|
return new While(A2, { invert: true, keyword: A1 });
|
|
}),
|
|
o("UNTIL Expression WHEN Expression", function() {
|
|
return new While(A2, { invert: true, guard: A4, keyword: A1 });
|
|
})
|
|
],
|
|
While: [
|
|
o("WhileSource Block", function() {
|
|
return A1.addBody(A2);
|
|
}),
|
|
o("Statement WhileSource", function() {
|
|
return A2.addBody(Block.wrap([A1]));
|
|
}),
|
|
o("Expression WhileSource", function() {
|
|
return A2.addBody(Block.wrap([A1]));
|
|
}),
|
|
o("Loop", function() {
|
|
return A1;
|
|
})
|
|
],
|
|
Loop: [
|
|
o("LOOP Block", function() {
|
|
return new While(new Literal("true", { keyword: A1 })).addBody(A2);
|
|
}),
|
|
o("LOOP Expression", function() {
|
|
return new While(new Literal("true", { keyword: A1 })).addBody(Block.wrap([A2]));
|
|
})
|
|
],
|
|
For: [
|
|
o("Statement ForBody", function() {
|
|
return A2.addBody([A1]);
|
|
}),
|
|
o("Expression ForBody", function() {
|
|
return A2.addBody([A1]);
|
|
}),
|
|
o("ForBody Block", function() {
|
|
return A1.addBody(A2);
|
|
}),
|
|
o("ForBody Block ELSE Block", function() {
|
|
return A1.addBody(A2).addElse(A4);
|
|
})
|
|
],
|
|
ForKeyword: [
|
|
o("FOR"),
|
|
o("POST_FOR")
|
|
],
|
|
ForBody: [
|
|
o("ForKeyword Range", function() {
|
|
return { source: new ValueNode(A2) };
|
|
}),
|
|
o("ForStart ForSource", function() {
|
|
return A2.configure({ own: A1.own, await: A1.await, name: A1[0], index: A1[1], keyword: A1.keyword, params: A1 });
|
|
})
|
|
],
|
|
ForStart: [
|
|
o("ForKeyword ForVariables", function() {
|
|
return (A2.keyword = A1) && A2;
|
|
}),
|
|
o("ForKeyword AWAIT ForVariables", function() {
|
|
return (A3.await = A2) && (A3.keyword = A1) && A3;
|
|
}),
|
|
o("ForKeyword OWN ForVariables", function() {
|
|
return (A3.own = true) && (A3.keyword = A1) && A3;
|
|
})
|
|
],
|
|
ForValue: [
|
|
o("Identifier"),
|
|
o("Identifier Type", function() {
|
|
return A1.set({ datatype: A2 });
|
|
}),
|
|
o("Array"),
|
|
o("Object")
|
|
],
|
|
ForVariables: [
|
|
o("ForValue", function() {
|
|
return [A1];
|
|
}),
|
|
o("ForValue , ForValue", function() {
|
|
return [A1, A3];
|
|
}),
|
|
o("ForValue , ForValue , ForValue", function() {
|
|
return [A1, A3, A5];
|
|
})
|
|
],
|
|
ForSource: [
|
|
o("FORIN Expression", function() {
|
|
return new ForIn({ source: A2 });
|
|
}),
|
|
o("FOROF Expression", function() {
|
|
return new ForOf({ source: A2, object: true });
|
|
}),
|
|
o("FORIN Expression WHEN Expression", function() {
|
|
return new ForIn({ source: A2, guard: A4 });
|
|
}),
|
|
o("FOROF Expression WHEN Expression", function() {
|
|
return new ForOf({ source: A2, guard: A4, object: true });
|
|
}),
|
|
o("FORIN Expression BY Expression", function() {
|
|
return new ForIn({ source: A2, step: A4 });
|
|
}),
|
|
o("FORIN Expression WHEN Expression BY Expression", function() {
|
|
return new ForIn({ source: A2, guard: A4, step: A6 });
|
|
}),
|
|
o("FORIN Expression BY Expression WHEN Expression", function() {
|
|
return new ForIn({ source: A2, step: A4, guard: A6 });
|
|
})
|
|
],
|
|
Switch: [
|
|
o("SWITCH Expression INDENT Whens OUTDENT", function() {
|
|
return new Switch(A2, A4);
|
|
}),
|
|
o("SWITCH Expression INDENT Whens ELSE Block Outdent", function() {
|
|
return new Switch(A2, A4, A6);
|
|
}),
|
|
o("SWITCH INDENT Whens OUTDENT", function() {
|
|
return new Switch(null, A3);
|
|
}),
|
|
o("SWITCH INDENT Whens ELSE Block OUTDENT", function() {
|
|
return new Switch(null, A3, A5);
|
|
})
|
|
],
|
|
Whens: [
|
|
o("When"),
|
|
o("Whens When", function() {
|
|
return A1.concat(A2);
|
|
})
|
|
],
|
|
When: [
|
|
o("LEADING_WHEN SimpleArgs Block", function() {
|
|
return [new SwitchCase(A2, A3)];
|
|
}),
|
|
o("LEADING_WHEN SimpleArgs Block TERMINATOR", function() {
|
|
return [new SwitchCase(A2, A3)];
|
|
})
|
|
],
|
|
IfBlock: [
|
|
o("IF Expression Block", function() {
|
|
return new If(A2, A3, { type: A1 });
|
|
}),
|
|
o("IfBlock ELSE IF Expression Block", function() {
|
|
return A1.addElse(new If(A4, A5, { type: A3 }));
|
|
}),
|
|
o("IfBlock ELIF Expression Block", function() {
|
|
return A1.addElse(new If(A3, A4, { type: A2 }));
|
|
}),
|
|
o("IfBlock ELSE Block", function() {
|
|
return A1.addElse(A3.set({ keyword: A2 }));
|
|
})
|
|
],
|
|
If: [
|
|
o("IfBlock"),
|
|
o("Statement POST_IF Expression", function() {
|
|
return new If(A3, new Block([A1]), { type: A2, statement: true });
|
|
}),
|
|
o("Expression POST_IF Expression", function() {
|
|
return new If(A3, new Block([A1]), { type: A2 });
|
|
})
|
|
],
|
|
Ternary: [
|
|
o("Expression ? Expression : Expression", function() {
|
|
return AST.If.ternary(A1, A3, A5);
|
|
})
|
|
],
|
|
Operation: [
|
|
o("NEW Expression", function() {
|
|
return AST.Instantiation.for(A2, A1);
|
|
}),
|
|
o("UNARY Expression", function() {
|
|
return AST.OP(A1, A2);
|
|
}),
|
|
o("SQRT Expression", function() {
|
|
return AST.OP(A1, A2);
|
|
}),
|
|
o("--- Expression", function() {
|
|
return AST.OP(A1, A2);
|
|
}),
|
|
o("+++ Expression", function() {
|
|
return AST.OP(A1, A2);
|
|
}),
|
|
o("- Expression", function() {
|
|
return AST.OP(A1, A2);
|
|
}, { prec: "UNARY" }),
|
|
o("+ Expression", function() {
|
|
return AST.OP(A1, A2);
|
|
}, { prec: "UNARY" }),
|
|
o("-- SimpleAssignable", function() {
|
|
return new UnaryOp(A1, null, A2);
|
|
}),
|
|
o("++ SimpleAssignable", function() {
|
|
return new UnaryOp(A1, null, A2);
|
|
}),
|
|
o("SimpleAssignable --", function() {
|
|
return new UnaryOp(A2, A1, null, true);
|
|
}),
|
|
o("SimpleAssignable ++", function() {
|
|
return new UnaryOp(A2, A1, null, true);
|
|
}),
|
|
o("Expression + Expression", function() {
|
|
return new Op(A2, A1, A3);
|
|
}),
|
|
o("Expression - Expression", function() {
|
|
return new Op(A2, A1, A3);
|
|
}),
|
|
o("Expression EXP Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("Expression MATH Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("Expression SHIFT Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("Expression COMPARE Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("Expression LOGIC Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("Expression NOT RELATION Expression", function() {
|
|
return AST.OP(A3, A1, A4).invert(A2);
|
|
}),
|
|
o("Expression RELATION Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("SimpleAssignable COMPOUND_ASSIGN Expression", function() {
|
|
return AST.OP(A2, A1, A3);
|
|
}),
|
|
o("SimpleAssignable COMPOUND_ASSIGN INDENT Expression Outdent", function() {
|
|
return AST.OP(A2, A1, A4.indented(A3, A5));
|
|
})
|
|
]
|
|
};
|
|
var operators = [
|
|
["left", ".", "?.", "::", ".:"],
|
|
["left", "CALL_START", "CALL_END"],
|
|
["nonassoc", "++", "--"],
|
|
["right", "UNARY", "NEW", "THROW", "SQRT", "NOT"],
|
|
["right", "AWAIT"],
|
|
["right", "EXP"],
|
|
["left", "MATH"],
|
|
["left", "+", "-", "+++", "---"],
|
|
["left", "SHIFT"],
|
|
["left", "RELATION"],
|
|
["left", "COMPARE"],
|
|
["left", "LOGIC"],
|
|
["right", "?"],
|
|
["nonassoc", "INDENT", "OUTDENT"],
|
|
["right", "=", ":", "COMPOUND_ASSIGN", "RETURN", "THROW", "EXTENDS"],
|
|
["right", "FORIN", "FOROF", "BY", "WHEN"],
|
|
["right", "TAG_END"],
|
|
["right", "IF", "ELSE", "FOR", "DO", "WHILE", "UNTIL", "LOOP", "SUPER", "CLASS", "MODULE", "TAG", "EVENT", "TRIGGER", "TAG_END", "IMPORT", "EXPORT"],
|
|
["right", "POST_IF", "POST_FOR"],
|
|
["right", "NEW_TAG"],
|
|
["right", "TAG_ATTR_SET"],
|
|
["right", "SPLAT"],
|
|
["left", "SELECTOR_START"],
|
|
["left", "CSS"]
|
|
];
|
|
var tokens = [];
|
|
for (let name in grammar) {
|
|
let alternatives;
|
|
alternatives = grammar[name];
|
|
let res = [];
|
|
for (let i = 0, items = iter$(alternatives), len = items.length, alt; i < len; i++) {
|
|
alt = items[i];
|
|
for (let j = 0, ary = iter$(alt[0].split(" ")), len2 = ary.length, token; j < len2; j++) {
|
|
token = ary[j];
|
|
if (!grammar[token]) {
|
|
tokens.push(token);
|
|
}
|
|
;
|
|
}
|
|
;
|
|
if (name === "Root") {
|
|
alt[1] = "return " + alt[1];
|
|
}
|
|
;
|
|
res.push(alt);
|
|
}
|
|
;
|
|
grammar[name] = res;
|
|
}
|
|
exports.parser = new Parser(
|
|
{
|
|
tokens: tokens.join(" "),
|
|
bnf: grammar,
|
|
operators: operators.reverse(),
|
|
startSymbol: "Root"
|
|
}
|
|
);
|
|
|