예제 #1
0
        private bool TryBuildTreeFromStack(bool StopOnError)
        {
            TValue VT = (TValue)Activator.CreateInstance(typeof(TValue));
            Stack <KeyValuePair <int, int> >   BackTrack          = new Stack <KeyValuePair <int, int> >();//стек пунктов для перебора с возвратом
            HashSet <KeyValuePair <int, int> > CheckedKernelItems = new HashSet <KeyValuePair <int, int> >();

            while (StateStack.TopElement().number != 0)
            {
                //если восстановление по ходу разбора
                //то выходим, встретив состояние, допускающее error
                if (StopOnError)
                {
                    if (FsaState.ParserTable != null &&
                        FsaState.ParserTable.ContainsKey(errorToken) &&
                        FsaState.ParserTable[errorToken] > 0) // shift
                    {
                        return(true);
                    }
                }
                State state    = StateStack.TopElement();
                int   ruleNum  = 0;                             //номер пункта
                int   pointPos = 0;                             //позиция точки в выбранной продукци

                //Формируем список еще не посещенных пунктов
                List <KeyValuePair <int, int> > ValidKernelItems = new List <KeyValuePair <int, int> >();
                foreach (KeyValuePair <int, int> p in state.kernelItems)
                {
                    if (!CheckedKernelItems.Contains(p))
                    {
                        ValidKernelItems.Add(p);
                    }
                }

                if (ValidKernelItems.Count == 0)
                {
                    //непосещенных пунктов не осталось - возврат
                    KeyValuePair <int, int> p = BackTrack.Pop();
                    ruleNum  = p.Key;
                    pointPos = p.Value;
                }
                else
                {
                    //Среди непосещенных находим пункт с точкой в самой правой позиции
                    foreach (KeyValuePair <int, int> p in ValidKernelItems)
                    {
                        if (p.Value > pointPos)
                        {
                            pointPos = p.Value;
                            ruleNum  = p.Key;
                        }
                    }
                    if (pointPos == 1)
                    {
                        //точка в 1 позиции - добавляем пункты на стек и берем последний из них
                        foreach (KeyValuePair <int, int> p in ValidKernelItems)
                        {
                            BackTrack.Push(p);
                            CheckedKernelItems.Add(p);
                        }
                        KeyValuePair <int, int> p2 = BackTrack.Pop();
                        ruleNum  = p2.Key;
                        pointPos = p2.Value;
                    }
                    else
                    {
                        //точка в 2+ позиции - готовимся к новому запуску перебора с возвратом
                        CheckedKernelItems.Clear();
                        BackTrack.Clear();
                    }
                }
                int count = rules[ruleNum].RightHandSide.Length - pointPos;
                //add items to stacks
                for (int i = 0; i < count; ++i)
                {
                    valueStack.Push(VT);
                    locationStack.Push(CurrentLocationSpan);
                    StateStack.Push(state);
                }
                //reduce
                Reduce(ruleNum);
            }
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Main entry point of the Shift-Reduce Parser.
        /// </summary>
        /// <returns>True if parse succeeds, else false for
        /// unrecoverable errors</returns>
        public bool Parse()
        {
            Initialize();       // allow derived classes to instantiate rules, states and nonTerminals

            NextToken = 0;
            FsaState  = states[0];

            StateStack.Push(FsaState);
            valueStack.Push(CurrentSemanticValue);
            LocationStack.Push(CurrentLocationSpan);

            while (true)
            {
#if TRACE_ACTIONS
                Console.Error.WriteLine("Entering state {0} ", FsaState.number);
                DisplayStack();
#endif
                int action = FsaState.defaultAction;

                if (FsaState.ParserTable != null)
                {
                    if (NextToken == 0)
                    {
                        // We save the last token span, so that the location span
                        // of production right hand sides that begin or end with a
                        // nullable production will be correct.
                        LastSpan  = scanner.yylloc;
                        NextToken = scanner.yylex();
#if TRACE_ACTIONS
                        Console.Error.WriteLine("Reading: Next token is {0}", TerminalToString(NextToken));
#endif
                    }
#if TRACE_ACTIONS
                    else
                    {
                        Console.Error.WriteLine("Next token is still {0}", TerminalToString(NextToken));
                    }
#endif
                    if (FsaState.ParserTable.ContainsKey(NextToken))
                    {
                        action = FsaState.ParserTable[NextToken];
                    }
                }

                if (action > 0)         // shift
                {
                    Shift(action);
                }
                else if (action < 0)   // reduce
                {
                    try {
                        Reduce(-action);
                        if (action == -1)       // accept
                        {
                            return(true);
                        }
                    }
                    catch (AbortException) {
                        return(false);
                    }
                    catch (AcceptException) {
                        return(true);
                    }
                    catch (ErrorException) {
                        if (!ErrorRecovery())
                        {
                            return(false);
                        }
                        else
                        {
                            throw;  // Rethrow x, preserving information.
                        }
                    }
                }
                else if (action == 0 && !ErrorRecovery()) // error
                {
                    return(false);
                }
            }
        }
        public bool Parse()
        {
            Initialize();

            NextToken = 0;
            FsaState  = states[0];

            StateStack.Push(FsaState);
            valueStack.Push(CurrentSemanticValue);
            LocationStack.Push(CurrentLocationSpan);

            while (true)
            {
#if TRACE_ACTIONS
                Console.Error.WriteLine("Entering state {0} ", FsaState.number);
#endif
                int action = FsaState.defaultAction;

                if (FsaState.ParserTable != null)
                {
                    if (NextToken == 0)
                    {
#if TRACE_ACTIONS
                        Console.Error.Write("Reading a token: ");
#endif
                        LastSpan  = scanner.yylloc;
                        NextToken = scanner.yylex();
                    }

#if TRACE_ACTIONS
                    Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
#endif
                    if (FsaState.ParserTable.ContainsKey(NextToken))
                    {
                        action = FsaState.ParserTable[NextToken];
                    }
                }

                if (action > 0)
                {
                    Shift(action);
                }
                else if (action < 0)
                {
                    try
                    {
                        Reduce(-action);
                        if (action == -1)
                        {
                            return(true);
                        }
                    }
                    catch (Exception x)
                    {
                        if (x is AbortException)
                        {
                            return(false);
                        }
                        else if (x is AcceptException)
                        {
                            return(true);
                        }
                        else if (x is ErrorException && !ErrorRecovery())
                        {
                            return(false);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                else if (action == 0)
                {
                    if (!ErrorRecovery())
                    {
                        return(false);
                    }
                }
            }
        }