lib/ll1/first.js
function first(FIRST, rule) {
  var terminals = new Set();
  var read = true;
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = rule[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var x = _step.value;
      if (!read) break;
      read = false;

      if (x.type === 'leaf') {
        terminals.add(x.terminal);
        break;
      }

      (0, _util.setaddall)(terminals, (0, _jsItertools.filter)(function (y) {
        return y !== _grammar.EW;
      }, FIRST.get(x.nonterminal)));
      read |= (0, _jsItertools.any)((0, _jsItertools.map)(function (y) {
        return y === _grammar.EW;
      }, FIRST.get(x.nonterminal)));
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return != null) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  if (read) terminals.add(_grammar.EW);
  return terminals;
}
function first(FIRST, rule) {
  var terminals = new Set();
  var read = true;
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = rule[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var x = _step.value;
      if (!read) break;
      read = false;

      if (x.type === 'leaf') {
        terminals.add(x.terminal);
        break;
      }

      (0, _util.setaddall)(terminals, (0, _jsItertools.filter)(function (y) {
        return y !== _grammar.EW;
      }, FIRST.get(x.nonterminal)));
      read |= (0, _jsItertools.any)((0, _jsItertools.map)(function (y) {
        return y === _grammar.EW;
      }, FIRST.get(x.nonterminal)));
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return != null) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  if (read) terminals.add(_grammar.EW);
  return terminals;
}
function first ( FIRST , rule ) { var terminals = new Set ( ) ; var read = true ; var _iteratorNormalCompletion = true ; var _didIteratorError = false ; var _iteratorError = undefined ; try { for ( var _iterator = rule [ Symbol . iterator ] ( ) , _step ; ! ( _iteratorNormalCompletion = ( _step = _iterator . next ( ) ) . done ) ; _iteratorNormalCompletion = true ) { var x = _step . value ; if ( ! read ) break ; read = false ; if ( x . type === 'leaf' ) { terminals . add ( x . terminal ) ; break ; } ( 0 , _util . setaddall ) ( terminals , ( 0 , _jsItertools . filter ) ( function ( y ) { return y !== _grammar . EW ; } , FIRST . get ( x . nonterminal ) ) ) ; read |= ( 0 , _jsItertools . any ) ( ( 0 , _jsItertools . map ) ( function ( y ) { return y === _grammar . EW ; } , FIRST . get ( x . nonterminal ) ) ) ; } } catch ( err ) { _didIteratorError = true ; _iteratorError = err ; } finally { try { if ( ! _iteratorNormalCompletion && _iterator . return != null ) { _iterator . return ( ) ; } } finally { if ( _didIteratorError ) { throw _iteratorError ; } } } if ( read ) terminals . add ( _grammar . EW ) ; return terminals ; }
Generate FIRST set for any rule given the FIRST sets for the nonterminals.

@param {Map} FIRST
@param {Array} rule
@returns {Set}
Generate FIRST set for any rule given the FIRST sets for the nonterminals .