public LLkParser(TableGenerator tg, IEnumerable <Token> input) { _tg = tg; _input = input.GetEnumerator(); _stack = new Stack <_Entry>(); _nodeType = LLNodeType.Initial; _current = new List <Token>(); }
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); }