Exemple #1
0
        private void PerformPanicRecovery(Lexeme z, List <ParserHead> shiftedHeads)
        {
            //Panic recovery
            //to the 1st head:
            //pop stack until there's a state S, which has a Goto action of a non-terminal A
            //discard input until there's an token a in Follow(A)
            //push Goto(s, A) into stack
            //discard all other heads

            m_heads.Clear();
            m_heads.AddRange(shiftedHeads.Where(h => h.ErrorRecoverLevel == 0));
            shiftedHeads.Clear();

            ParserHead errorHead1 = m_errorCandidates[0];

            m_errorCandidates.Clear();

            IProduction p = errorHead1.PanicRecover(m_transitions, z.Value.Span, z.IsEndOfStream);

            ProductionBase productionBase = p as ProductionBase;

            if (productionBase != null)
            {
                var follow = productionBase.Info.Follow;

                m_heads.Add(errorHead1);

                throw new PanicRecoverException(follow);
            }
        }
Exemple #2
0
        private void PerformPanicRecovery(Lexeme z, List <ParserHead> shiftedHeads)
        {
            //Panic recovery
            //to the 1st head:
            //pop stack until there's a state S, which has a Goto action of a non-terminal A
            //discard input until there's an token a in Follow(A)
            //push Goto(s, A) into stack
            //discard all other heads

            m_heads.Clear();
            m_heads.AddRange(shiftedHeads.Where(h => h.ErrorRecoverLevel == 0));
            shiftedHeads.Clear();

            ParserHead errorHead1 = m_errorCandidates[0];

            m_errorCandidates.Clear();

            var candidates = errorHead1.PanicRecover(m_transitions, z.Value.Span, z.IsEndOfStream);

            ISet <IProduction> follows = new HashSet <IProduction>();

            foreach (var candidate in candidates)
            {
                ProductionBase p = candidate.Item2 as ProductionBase;
                follows.UnionWith(p.Info.Follow);

                m_heads.Add(candidate.Item1);
            }
            if (m_heads.Count > 0)
            {
                throw new PanicRecoverException(follows);
            }
            else
            {
                throw new ParsingFailureException("There's no way to recover from parser error");
            }
        }
Exemple #3
0
        private void RecoverError(Lexeme z)
        {
            List <ParserHead> shiftedHeads = m_shiftedHeads;

            m_heads.Clear();
            int errorHeadCount = m_errorCandidates.Count;

            Debug.Assert(errorHeadCount > 0);

            if (errorHeadCount > c_panicRecoveryThreshold)
            {
                //Panic recovery
                //to the 1st head:
                //pop stack until there's a state S, which has a Goto action of a non-terminal A
                //discard input until there's an token a in Follow(A)
                //push Goto(s, A) into stack
                //discard all other heads

                m_heads.Clear();
                m_heads.AddRange(shiftedHeads.Where(h => h.ErrorRecoverLevel == 0));
                shiftedHeads.Clear();

                ParserHead errorHead1 = m_errorCandidates[0];
                m_errorCandidates.Clear();

                IProduction p = errorHead1.PanicRecover(m_transitions, z.Value.Span);

                var follow = (p as ProductionBase).Info.Follow;

                m_heads.Add(errorHead1);

                throw new PanicRecoverException(follow);
            }

            for (int i = 0; i < errorHeadCount; i++)
            {
                var head = m_errorCandidates[i];

                if (!z.IsEndOfStream)
                {
                    //option 1: remove
                    //remove current token and continue
                    var deleteHead = head.Clone();

                    deleteHead.IncreaseErrorRecoverLevel();
                    deleteHead.AddError(new ErrorRecord(m_errorDef.TokenUnexpectedId, z.Value.Span)
                    {
                        ErrorArgument = z.Value
                    });

                    shiftedHeads.Add(deleteHead);

                    //option 2: replace
                    //replace the current input char with all possible shifts token and continue
                    ReduceAndShiftForRecovery(z, head, shiftedHeads, m_errorDef.TokenMistakeId);
                }

                //option 3: insert
                //insert all possible shifts token and continue
                ReduceAndShiftForRecovery(z, head, m_heads, m_errorDef.TokenMissingId);
            }
        }