"use strict"; /** @fileOverview Implements `class page.EBNF.Seq`. * @author Axel T. Schreiner <ats@cs.rit.edu> * @version 1.5.0 */ /** Creates a new representation of a sequence for EBNF. * @class Represents a sequence for EBNF. * @private * * @example * groups: a b | c d; * * @param {eNode[]} _nodes sequence, at least two; null during unmarshalling. * * @property {eNode[]} nodes descendants, at least two. * @property {page.BNF.NT} nt corresponding non-terminal for BNF. * @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.Seq = function (_nodes) { this.nodes = _nodes; this.nt = undefined; this.empty = undefined; this.first = undefined; this.follow = undefined; }; page.baseclass(page.EBNF.Seq, 'page.EBNF.Seq'); /** Displays a sequence in EBNF notation. * @returns {string}. */ page.EBNF.Seq.prototype.toString = function () { return this.nodes.map(function (node) { return node instanceof page.EBNF.Alt || node instanceof page.EBNF.Seq ? '(' + node + ')' : node; }).join(' '); }; /** Called once by {@link page.EBNF#init} to recursively translate into BNF. * * a b * * is translated to * * $#: a b; * * @private * * @param {page.EBNF} _grammar object to which the construct belongs. * @param {page.EBNF.NT} [_nt] left-hand side, if known; avoids the need for a fresh non-terminal. * * @returns {page.BNF.NT} non-terminal representing the translated construct. */ page.EBNF.Seq.prototype.toBNF = function (_grammar, _nt) { _grammar.assert('__WHERE__', !this.nt); _grammar.assert('__WHERE__', this.nodes.length > 1); var result = this.nt = _nt ? _nt : _grammar.bnf.nt('$'); // $# var at = _grammar.bnf.rules.length; // placeholder _grammar.bnf.rules.push(null); _grammar.bnf.rules[at] = _grammar.bnf.rule(result, this.nodes.map(function (node) { return node instanceof page.BNF.T ? node : node.toBNF(_grammar); })); 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 {@link page.EBNF.Seq}`.nt` * and then delegates to the descendants. * @private */ page.EBNF.Seq.prototype.init = function () { this.assert('__WHERE__', !this.first); this.empty = this.nt.empty; this.first = this.nt.first; this.follow = this.nt.follow; this.nodes.forEach(function (node) { if (node.init) node.init(); }); };