Source: EBNF/Rule.js

"use strict";

/** @fileOverview Implements `class page.EBNF.Rule extends page.BNF.Rule`.
  * @author Axel T. Schreiner <ats@cs.rit.edu>
  * @version 1.5.0
  */

/** Creates a new EBNF rule.
  * Sets rule's non-terminal's {@link page.EBNF.NT}`.rules`.
  * @class Represents an EBNF rule.
  * @extends page.BNF.Rule
  * @private
  *
  * @param {page.EBNF.NT} _nt  left-hand side, non-terminal.
  * @param {eNode} _symbol right-hand side.
  *
  * @property {page.EBNF.NT} nt rule's non-terminal (left-hand side).
  * @property {eNode} symbol rule's right-hand side.
  * @property {number} index rule's index in {@link page.EBNF}`.rules`.
  * @property {boolean} empty true if no input can be accepted.
  * @property {Map} first terminals at front, maps ord to {@link page.BNF.T}.
  * @property {Map} follow terminals following, maps ord to {@link page.BNF.T}.
  */
page.EBNF.Rule = function (_nt, _symbol) {
  page.BNF.Rule.call(this, _nt, []);

  delete this.symbols;
  this.symbol = _symbol;
  delete this.reached;
  delete this.finite;
};

page.subclass(page.EBNF.Rule, 'page.EBNF.Rule', page.BNF.Rule);

/** Displays a rule in EBNF notation.
  * @override
  * @variation EBNF
  *
  * @returns {string}
  */
page.EBNF.Rule.prototype.toString = function () {
  return this.nt + ': ' + this.symbol + ';';
};

/** Displays index, rule, `empty`, and contents of `first` and `follow`.
  * @override
  * @variation EBNF
  * @returns {string}
  */
page.EBNF.Rule.prototype.dump = function () {
  var result = (this.index >= 0 ? (' ' + this.index).substr(-2) + ': ' : '') + this.toString();

  if (this.empty)
    result += '\n\tempty: true';
    
  for (var set in { first:0, follow:0 })
    if (set in this) {
      var r = '';
      for (var ord in this[set]) r += ' ' + this[set][ord];
      if (r.length) result += '\n\t' + set + ':' + r;
    }

  return result;
};

/** Called once by {@link page.EBNF#init} to complete EBNF grammar initialization.
  * Imports {@link page.BNF.NT}`.empty`, {@link page.BNF.NT}`.first`, and {@link page.BNF.NT}`.follow` from `.nt`.
  * Delegates to `.symbol`.
  * @private
  */
page.EBNF.Rule.prototype.init = function () {
  if (this.symbol.init) this.symbol.init();
  this.empty = this.nt.empty;
  this.first = this.nt.first;
  this.follow = this.nt.follow;
};