void _Panic() { // This is primitive. Should see if the Dragon Book has something better _nodeType = LRNodeType.Error; var state = _stack.Peek(); var d = _parseTable[state]; (int RuleOrStateId, string Left, string[] Right)e; _errorToken.Symbol = "#ERROR"; _errorToken.SymbolId = _symbolIds[_errorToken.Symbol]; _errorToken.Value = _tokenEnum.Current.Value; _errorToken.Line = _tokenEnum.Current.Line; _errorToken.Column = _tokenEnum.Current.Column; _errorToken.Position = _tokenEnum.Current.Position; var s = _tokenEnum.Current.Symbol; if (!d.TryGetValue(s, out e) && "#EOS" != s) { _errorToken.Value += _tokenEnum.Current.Value; while (_tokenEnum.MoveNext() && "#EOS" != (s = _tokenEnum.Current.Symbol)) { if (!d.TryGetValue(s, out e)) { _errorToken.Value += _tokenEnum.Current.Value; } else { break; } } } }
public Lalr1DebugParser(CfgDocument cfg, IEnumerable <Token> tokenizer, CfgLalr1ParseTable parseTable = null) { _cfg = cfg; _PopulateAttrs(); _stack = new Stack <int>(); _tokenEnum = tokenizer.GetEnumerator(); _parseTable = parseTable ?? cfg.ToLalr1ParseTable(); _nodeType = LRNodeType.Initial; }
public override void Restart() { if (null == _tokenEnum) { throw new ObjectDisposedException(GetType().Name); } _tokenEnum.Reset(); _stack.Clear(); _nodeType = LRNodeType.Initial; }
public GlrWorker(GlrTableParser outer, int id, int[][][][] parseTable, int errorId, int eosId, int[] errorSentinels, IList <GlrWorker> workers, LookAheadEnumerator tokenEnum) { _Outer = outer; Id = id; _parseTable = parseTable; _errorId = errorId; _eosId = eosId; _tokenEnum = tokenEnum; _stack = new List <int>(); Index = 0; _tupleIndex = 0; _workers = workers; _errorSentinels = errorSentinels; ErrorTokens = new Queue <Token>(); _continuation = false; NodeType = LRNodeType.Initial; }
public Lalr1TableParser(int[][][] parseTable, string[] symbols, int[] nodeFlags, int[] substitutions, KeyValuePair <string, object>[][] attributeSets, IEnumerable <Token> tokenizer) { _parseTable = parseTable; _symbols = symbols; _nodeFlags = nodeFlags; _substitutions = substitutions; _attributeSets = attributeSets; _eosId = Array.IndexOf(symbols, "#EOS"); _errorId = Array.IndexOf(symbols, "#ERROR"); if (0 > _eosId || 0 > _errorId) { throw new ArgumentException("Error in symbol table", "symbols"); } _stack = new Stack <int>(); _tokenEnum = tokenizer.GetEnumerator(); _nodeType = LRNodeType.Initial; }
public GlrWorker(GlrTableParser outer, GlrWorker worker, int tupleIndex) { _Outer = outer; _parseTable = worker._parseTable; _errorId = worker._errorId; _eosId = worker._eosId; _errorSentinels = worker._errorSentinels; ErrorTokens = new Queue <Token>(worker.ErrorTokens); _tokenEnum = worker._tokenEnum; _stack = new List <int>(worker._stack.Count); _stack.AddRange(worker._stack); Index = worker.Index; _tupleIndex = tupleIndex; NodeType = worker.NodeType; Id = outer.NextWorkerId; CurrentToken = worker.CurrentToken; ++outer.NextWorkerId; _continuation = true; _workers = worker._workers; }
void _Panic() { // This is primitive. Should see if the Dragon Book has something better _nodeType = LRNodeType.Error; var state = _stack.Peek(); var d = _parseTable[state]; int[] e; _errorToken.Symbol = "#ERROR"; _errorToken.SymbolId = _errorId; _errorToken.Value = _tokenEnum.Current.Value; _errorToken.Line = _tokenEnum.Current.Line; _errorToken.Column = _tokenEnum.Current.Column; _errorToken.Position = _tokenEnum.Current.Position; var s = _tokenEnum.Current.SymbolId; if (_errorId != s && null != (e = d[s]) && _eosId != s) { _errorToken.Value += _tokenEnum.Current.Value; while (_tokenEnum.MoveNext() && _eosId != (s = _tokenEnum.Current.SymbolId)) { if (null != (e = d[s])) { _errorToken.Value += _tokenEnum.Current.Value; } else { break; } } } else { _errorToken.Value += _tokenEnum.Current.Value; _tokenEnum.MoveNext(); } }
public bool Read() { if (0 != ErrorTokens.Count) { Token tok = ErrorTokens.Dequeue(); tok.SymbolId = _errorId; CurrentToken = tok; return(true); } if (_continuation) { _continuation = false; } else { LRNodeType n = NodeType; if (LRNodeType.Shift == n) { _ReadNextToken(); } else if (LRNodeType.Initial == n) { _stack.Add(0); _ReadNextToken(); NodeType = LRNodeType.Error; } else if (LRNodeType.EndDocument == n) { return(false); } else if (LRNodeType.Accept == n) { NodeType = LRNodeType.EndDocument; _stack.Clear(); return(true); } } if (0 < _stack.Count) { var entry = _parseTable[_stack[_stack.Count - 1]]; if (_errorId == CurrentToken.SymbolId) { _tupleIndex = 0; _Panic(); return(true); } var tbl = entry[CurrentToken.SymbolId]; if (null == tbl) { _tupleIndex = 0; _Panic(); return(true); } int[] trns = tbl[_tupleIndex]; // only create more if we're on the first index // that way we won't create spurious workers if (0 == _tupleIndex) { for (var i = 1; i < tbl.Length; ++i) { _workers.Add(new GlrWorker(_Outer, this, i)); } } if (null == trns) { _Panic(); _tupleIndex = 0; return(true); } if (1 == trns.Length) { if (-1 != trns[0]) // shift { NodeType = LRNodeType.Shift; _stack.Add(trns[0]); _tupleIndex = 0; return(true); } else { // accept //throw if _tok is not $ (end) if (_eosId != CurrentToken.SymbolId) { _Panic(); _tupleIndex = 0; return(true); } NodeType = LRNodeType.Accept; _stack.Clear(); _tupleIndex = 0; return(true); } } else // reduce { RuleDefinition = new int[trns.Length - 1]; for (var i = 1; i < trns.Length; ++i) { RuleDefinition[i - 1] = trns[i]; } for (var i = 2; i < trns.Length; ++i) { _stack.RemoveAt(_stack.Count - 1); } // There is a new number at the top of the stack. // This number is our temporary state. Get the symbol // from the left-hand side of the rule #. Treat it as // the next input token in the GOTO table (and place // the matching state at the top of the set stack). // - Stephen Jackson, https://web.cs.dal.ca/~sjackson/lalr1.html var state = _stack[_stack.Count - 1]; var e = _parseTable[state]; if (null == e) { _Panic(); _tupleIndex = 0; return(true); } _stack.Add(_parseTable[state][trns[1]][0][0]); NodeType = LRNodeType.Reduce; _tupleIndex = 0; return(true); } } else { // if we already encountered an error // return EndDocument in this case, since the // stack is empty there's nothing to do NodeType = LRNodeType.EndDocument; _tupleIndex = 0; return(true); } }
public override bool Read() { if (_nodeType == LRNodeType.Initial) { _stack.Push(0); // push initial state if (!_tokenEnum.MoveNext()) { throw new Exception("Error in tokenizer implementation: Expecting #EOS token"); } } else if (LRNodeType.Accept == _nodeType) { _nodeType = LRNodeType.EndDocument; return(true); } else if (LRNodeType.EndDocument == _nodeType) { return(false); } else if (_eosId == _tokenEnum.Current.SymbolId && LRNodeType.Error == _nodeType) { return(false); } if (LRNodeType.Error != _nodeType) { if (!ShowHidden) { while (_IsHidden(_tokenEnum.Current.SymbolId)) { _tokenEnum.MoveNext(); } } else if (_IsHidden(_tokenEnum.Current.SymbolId)) { _token = _tokenEnum.Current; _nodeType = LRNodeType.Shift; _tokenEnum.MoveNext(); return(true); } } var entry = _parseTable[_stack.Peek()]; //(int RuleOrStateId, int Left, int[] Right) trns; if (_errorId == _tokenEnum.Current.SymbolId) { _Panic(); return(true); } int[] trns = entry[_tokenEnum.Current.SymbolId]; if (null == trns) { _Panic(); return(true); } if (1 == trns.Length) // shift or accept { if (-1 != trns[0]) // shift { _nodeType = LRNodeType.Shift; _token = _tokenEnum.Current; _tokenEnum.MoveNext(); _stack.Push(trns[0]); return(true); } else { // accept //throw if _tok is not $ (end) if (_eosId != _tokenEnum.Current.SymbolId) { _Panic(); return(true); } _nodeType = LRNodeType.Accept; _stack.Clear(); return(true); } } else // reduce { _ruleDef = new int[trns.Length - 1]; for (var i = 1; i < trns.Length; i++) { _ruleDef[i - 1] = trns[i]; } for (int i = 2; i < trns.Length; ++i) { _stack.Pop(); } // There is a new number at the top of the stack. // This number is our temporary state. Get the symbol // from the left-hand side of the rule #. Treat it as // the next input token in the GOTO table (and place // the matching state at the top of the set stack). _stack.Push(_parseTable[_stack.Peek()][trns[1]][0]); _nodeType = LRNodeType.Reduce; return(true); } }
public override bool Read() { if (_nodeType == LRNodeType.Initial) { _stack.Push(0); // push initial state if (!_tokenEnum.MoveNext()) { throw new Exception("Error in tokenizer implementation: Expecting #EOS token"); } } else if (LRNodeType.Accept == _nodeType) { _nodeType = LRNodeType.EndDocument; return(true); } else if (LRNodeType.EndDocument == _nodeType) { return(false); } else if ("#EOS" == _tokenEnum.Current.Symbol && LRNodeType.Error == _nodeType) { return(false); } if (LRNodeType.Error != _nodeType) { if (!ShowHidden) { while (_IsHidden(_tokenEnum.Current.Symbol)) { _tokenEnum.MoveNext(); } } else if (_IsHidden(_tokenEnum.Current.Symbol)) { _token = _tokenEnum.Current; _nodeType = LRNodeType.Shift; _tokenEnum.MoveNext(); return(true); } } var entry = _parseTable[_stack.Peek()]; (int RuleOrStateId, string Left, string[] Right)trns; if (!entry.TryGetValue(_tokenEnum.Current.Symbol, out trns)) { _Panic(); return(true); } if (null == trns.Right) // shift or accept { if (-1 != trns.RuleOrStateId) // shift { _nodeType = LRNodeType.Shift; _token = _tokenEnum.Current; _tokenEnum.MoveNext(); _stack.Push(trns.RuleOrStateId); return(true); } else { // accept //throw if _tok is not $ (end) if ("#EOS" != _tokenEnum.Current.Symbol) { _Panic(); return(true); } _nodeType = LRNodeType.Accept; _stack.Clear(); return(true); } } else // reduce { _ruleDef = new string[trns.Right.Length + 1]; _ruleDef[0] = trns.Left; trns.Right.CopyTo(_ruleDef, 1); for (int i = 0; i < trns.Right.Length; ++i) { if (null != trns.Right[i]) { _stack.Pop(); } } // There is a new number at the top of the stack. // This number is our temporary state. Get the symbol // from the left-hand side of the rule #. Treat it as // the next input token in the GOTO table (and place // the matching state at the top of the set stack). _stack.Push(_parseTable[_stack.Peek()][trns.Left].RuleOrStateId); _nodeType = LRNodeType.Reduce; return(true); } }