UNPKG

imba

Version:

Intuitive and powerful language for building webapps that fly

3,245 lines • 100 kB
var __commonJS = (callback, module2) => () => {
  if (!module2) {
    module2 = {exports: {}};
    callback(module2.exports, module2);
  }
  return module2.exports;
};

// vendor/jison/util/typal.js
var require_typal = __commonJS((exports2) => {
  var typal2 = function() {
    var create = Object.create || function(o2) {
      function F() {
      }
      F.prototype = o2;
      return new F();
    };
    var position = /^(before|after)/;
    function layerMethod(k, fun) {
      var pos = k.match(position)[0], key = k.replace(position, ""), prop = this[key];
      if (pos === "after") {
        this[key] = function() {
          var ret = prop.apply(this, arguments);
          var args = [].slice.call(arguments);
          args.splice(0, 0, ret);
          fun.apply(this, args);
          return ret;
        };
      } else if (pos === "before") {
        this[key] = function() {
          fun.apply(this, arguments);
          var ret = prop.apply(this, arguments);
          return ret;
        };
      }
    }
    function typal_mix() {
      var self2 = this;
      for (var i = 0, o2, k; i < arguments.length; i++) {
        o2 = arguments[i];
        if (!o2)
          continue;
        if (Object.prototype.hasOwnProperty.call(o2, "constructor"))
          this.constructor = o2.constructor;
        if (Object.prototype.hasOwnProperty.call(o2, "toString"))
          this.toString = o2.toString;
        for (k in o2) {
          if (Object.prototype.hasOwnProperty.call(o2, k)) {
            if (k.match(position) && typeof this[k.replace(position, "")] === "function")
              layerMethod.call(this, k, o2[k]);
            else
              this[k] = o2[k];
          }
        }
      }
      return this;
    }
    return {
      mix: typal_mix,
      beget: function typal_beget() {
        return arguments.length ? typal_mix.apply(create(this), arguments) : create(this);
      },
      construct: function typal_construct() {
        var o2 = typal_mix.apply(create(this), arguments);
        var constructor = o2.constructor;
        var Klass = o2.constructor = function() {
          return constructor.apply(this, arguments);
        };
        Klass.prototype = o2;
        Klass.mix = typal_mix;
        return Klass;
      },
      constructor: function typal_constructor() {
        return this;
      }
    };
  }();
  if (typeof exports2 !== "undefined")
    exports2.typal = typal2;
});

// vendor/jison/util/set.js
var require_set = __commonJS((exports2) => {
  var typal2 = require_typal().typal;
  var setMixin = {
    constructor: function Set_constructor(set, raw) {
      this._items = [];
      if (set && set.constructor === Array)
        this._items = raw ? set : set.slice(0);
      else if (arguments.length)
        this._items = [].slice.call(arguments, 0);
    },
    concat: function concat(setB) {
      this._items.push.apply(this._items, setB._items || setB);
      return this;
    },
    eq: function eq(set) {
      return this._items.length === set._items.length && this.subset(set);
    },
    indexOf: function indexOf(item) {
      if (item && item.eq) {
        for (var k = 0; k < this._items.length; k++)
          if (item.eq(this._items[k]))
            return k;
        return -1;
      }
      return this._items.indexOf(item);
    },
    union: function union(set) {
      return new Set2(this._items).concat(this.complement(set));
    },
    intersection: function intersection(set) {
      return this.filter(function(elm) {
        return set.contains(elm);
      });
    },
    complement: function complement(set) {
      var that = this;
      return set.filter(function sub_complement(elm) {
        return !that.contains(elm);
      });
    },
    subset: function subset(set) {
      var cont = true;
      for (var i = 0; i < this._items.length && cont; i++) {
        cont = cont && set.contains(this._items[i]);
      }
      return cont;
    },
    superset: function superset(set) {
      return set.subset(this);
    },
    joinSet: function joinSet(set) {
      return this.concat(this.complement(set));
    },
    contains: function contains(item) {
      return this.indexOf(item) !== -1;
    },
    item: function item(v, val) {
      return this._items[v];
    },
    i: function i(v, val) {
      return this._items[v];
    },
    first: function first() {
      return this._items[0];
    },
    last: function last() {
      return this._items[this._items.length - 1];
    },
    size: function size() {
      return this._items.length;
    },
    isEmpty: function isEmpty() {
      return this._items.length === 0;
    },
    copy: function copy() {
      return new Set2(this._items);
    },
    toString: function toString() {
      return this._items.toString();
    }
  };
  "push shift unshift forEach some every join sort".split(" ").forEach(function(e, i) {
    setMixin[e] = function() {
      return Array.prototype[e].apply(this._items, arguments);
    };
    setMixin[e].name = e;
  });
  "filter slice map".split(" ").forEach(function(e, i) {
    setMixin[e] = function() {
      return new Set2(Array.prototype[e].apply(this._items, arguments), true);
    };
    setMixin[e].name = e;
  });
  var Set2 = typal2.construct(setMixin).mix({
    union: function(a, b) {
      var ar = {};
      for (var k = a.length - 1; k >= 0; --k) {
        ar[a[k]] = true;
      }
      for (var i = b.length - 1; i >= 0; --i) {
        if (!ar[b[i]]) {
          a.push(b[i]);
        }
      }
      return a;
    }
  });
  if (typeof exports2 !== "undefined")
    exports2.Set = Set2;
});

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