Пример #1
0
        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;
                    }
                }
            }
        }
Пример #2
0
 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;
 }
Пример #3
0
 public override void Restart()
 {
     if (null == _tokenEnum)
     {
         throw new ObjectDisposedException(GetType().Name);
     }
     _tokenEnum.Reset();
     _stack.Clear();
     _nodeType = LRNodeType.Initial;
 }
Пример #4
0
 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;
 }
Пример #5
0
        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;
        }
Пример #6
0
 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;
 }
Пример #7
0
        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();
            }
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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);
            }
        }