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