"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;
};