'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * The MIT License (MIT)
 * Copyright (c) 2015-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
 */

var MODES = exports.MODES = {
  LR0: 'LR0',
  SLR1: 'SLR1',
  LALR1: 'LALR1',
  LALR1_BY_SLR1: 'LALR1_BY_SLR1',
  LALR1_BY_CLR1: 'LALR1_BY_CLR1',
  LALR1_EXTENDED: 'LALR1_EXTENDED',
  CLR1: 'CLR1',
  LL1: 'LL1'
};

/**
 * Grammar/parser mode.
 */

var GrammarMode = function () {
  function GrammarMode() {
    var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MODES.LR0;

    _classCallCheck(this, GrammarMode);

    mode = mode.toUpperCase();

    if (!MODES.hasOwnProperty(mode)) {
      throw new TypeError('\n"' + mode + '" is not a valid parsing mode. ' + ('Valid modes are: ' + Object.keys(MODES).join(', ') + '.\n'));
    }

    this._mode = mode;
  }

  _createClass(GrammarMode, [{
    key: 'getRaw',
    value: function getRaw() {
      return this._mode;
    }
  }, {
    key: 'isLL',
    value: function isLL() {
      return this._isMode(MODES.LL1);
    }
  }, {
    key: 'isLR',
    value: function isLR() {
      return !this.isLL();
    }
  }, {
    key: 'usesLookaheadSet',
    value: function usesLookaheadSet() {
      return this.isLALR1ByCLR1() || this.isCLR1();
    }
  }, {
    key: 'isLR0',
    value: function isLR0() {
      return this._isMode(MODES.LR0);
    }
  }, {
    key: 'isSLR1',
    value: function isSLR1() {
      return this._isMode(MODES.SLR1);
    }
  }, {
    key: 'isLALR1',
    value: function isLALR1() {
      // Default algorithm for LALR(1) is "LALR(1) by SLR(1)".
      return this.isLALR1BySLR1() || this._isMode(MODES.LALR1);
    }
  }, {
    key: 'isLALR1BySLR1',
    value: function isLALR1BySLR1() {
      return this._isMode(MODES.LALR1_BY_SLR1);
    }
  }, {
    key: 'isLALR1ByCLR1',
    value: function isLALR1ByCLR1() {
      return this._isMode(MODES.LALR1_BY_CLR1);
    }
  }, {
    key: 'isLALR1Extended',
    value: function isLALR1Extended() {
      // Special grammar mode, where productions are built from
      // the LR(0) automation in the "LALR(1) by SLR(1)" algorithm.
      return this._isMode(MODES.LALR1_EXTENDED);
    }
  }, {
    key: 'isCLR1',
    value: function isCLR1() {
      return this._isMode(MODES.CLR1);
    }
  }, {
    key: '_isMode',
    value: function _isMode(mode) {
      return this._mode === mode;
    }

    /**
     * Returns string representation of a mode.
     * LR0 -> LR(0)
     */

  }, {
    key: 'toString',
    value: function toString() {
      return this._mode.slice(0, -1) + '(' + this._mode[this._mode.length - 1] + ')';
    }
  }]);

  return GrammarMode;
}();

exports.default = GrammarMode;