public GlrTableParser(int[][][][] parseTable, string[] symbolTable, ParseAttribute[][] attributes, int[] errorSentinels, IEnumerable <Token> tokenizer, int maxErrorCount)
        {
            _parseTable  = parseTable;
            _symbolTable = symbolTable;

            _attributes     = attributes;
            _errorSentinels = errorSentinels;
            _eosId          = Array.IndexOf(symbolTable, "#EOS");
            if (0 > _eosId)
            {
                throw new ArgumentException("Error in symbol table", "symbolTable");
            }
            _errorId = Array.IndexOf(symbolTable, "#ERROR");
            if (0 > _errorId)
            {
                throw new ArgumentException("Error in symbol table", "symbolTable");
            }
            _tokenEnum     = new LookAheadEnumerator(tokenizer.GetEnumerator());
            _maxErrorCount = maxErrorCount;
            NextWorkerId   = 1;
            _workerIndex   = 0;
            _workers       = new List <GlrWorker>(8);
            if (_tokenEnum.MoveNext())
            {
                _workers.Add(new GlrWorker(this, NextWorkerId, _parseTable, _errorId, _eosId, _errorSentinels, _workers, _tokenEnum));
                ++NextWorkerId;
            }
        }
        public bool Read()
        {
            if (0 == _workers.Count)
            {
                return(false);
            }
            _workerIndex = (_workerIndex + 1) % _workers.Count;
            _worker      = _workers[_workerIndex];
            while (!_worker.Read())
            {
                _workers.RemoveAt(_workerIndex);
                if (_workerIndex == _workers.Count)
                {
                    _workerIndex = 0;
                }
                if (0 == _workers.Count)
                {
                    return(false);
                }
                _worker = _workers[_workerIndex];
            }
            var min = int.MaxValue;
            var ic  = _workers.Count;

            for (var i = 0; i < ic; ++i)
            {
                GlrWorker w = _workers[i];
                if (0 < i && w.ErrorCount > _maxErrorCount)
                {
                    _workers.RemoveAt(i);
                    --i;
                    --ic;
                }
                if (min > w.Index)
                {
                    min = w.Index;
                }
                if (0 == min)
                {
                    i = ic;                     // break
                }
            }
            var j = min;

            while (j > 0)
            {
                _tokenEnum.MoveNext();
                --j;
            }
            for (j = 0; j < ic; ++j)
            {
                GlrWorker w = _workers[j];
                w.Index -= min;
            }

            return(true);
        }