Пример #1
0
 public LLkParser(TableGenerator tg, IEnumerable <Token> input)
 {
     _tg       = tg;
     _input    = input.GetEnumerator();
     _stack    = new Stack <_Entry>();
     _nodeType = LLNodeType.Initial;
     _current  = new List <Token>();
 }
Пример #2
0
        public bool Read()
        {
            var n = NodeType;

            if (LLNodeType.Error == n && 0 == _current.Count)
            {
                _errorToken.Symbol = null;
                _stack.Clear();
                return(true);
            }
            if (LLNodeType.Initial == n)
            {
                _stack.Push(new _Entry(0));                 // start at T0
                var kk = 0;
                // read k tokens from the input
                while (_input.MoveNext() && kk < _tg.k)
                {
                    _current.Add(_input.Current);
                    ++kk;
                }
                return(true);
            }
            // clear the error status
            _errorToken.Symbol = null;
            if (0 < _stack.Count)
            {
                var entry = _stack.Peek();
                var sid   = _stack.Peek();
                if (entry.IsEndSymbol)
                {
                    _nodeType = LLNodeType.EndNonTerminal;
                    _stack.Pop();
                    return(true);
                }
                if (entry.Symbol == _input.Current.Symbol)                 // terminal
                {
                    // lex the next token
                    _input.MoveNext();

                    _stack.Pop();
                    return(true);
                }
                // non-terminal
                Dictionary <string, CfgRule> d;
                if (_parseTable.TryGetValue(sid, out d))
                {
                    CfgRule rule;
                    if (d.TryGetValue(_input.Current.Symbol, out rule))
                    {
                        _stack.Pop();

                        // store the end non-terminal marker for later
                        _stack.Push(string.Concat("#END ", sid));

                        // push the rule's derivation onto the stack in reverse order
                        var ic = rule.Right.Count;
                        for (var i = ic - 1; 0 <= i; --i)
                        {
                            sid = rule.Right[i];
                            _stack.Push(sid);
                        }
                        return(true);
                    }
                    _Panic();
                    return(true);
                }
                _Panic();
                return(true);
            }
            // last symbol must be the end of the input stream or there's a problem
            if ("#EOS" != _input.Current.Symbol)
            {
                _Panic();
                return(true);
            }
            return(false);
        }