Beispiel #1
0
        private void Reduce(int ruleNumber)
        {
#if TRACE_ACTIONS
            DisplayRule(ruleNumber);
#endif
            Rule rule = rules[ruleNumber];
            //
            //  Default actions for unit productions.
            //
            if (rule.RightHandSide.Length == 1)
            {
                CurrentSemanticValue = valueStack.TopElement();    // Default action: $$ = $1;
                CurrentLocationSpan  = LocationStack.TopElement(); // Default action "@$ = @1;
            }
            else
            {
                if (rule.RightHandSide.Length == 0)
                {
                    // Create a new blank value.
                    // Explicit semantic action may mutate this value
                    CurrentSemanticValue = default(TValue);
                    // The location span for an empty production will start with the
                    // beginning of the next lexeme, and end with the finish of the
                    // previous lexeme.  This gives the correct behaviour when this
                    // nonsense value is used in later Merge operations.
                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
                                           scanner.yylloc.Merge(LastSpan) :
                                           default(TSpan));
                }
                else
                {
                    // Default action: $$ = $1;
                    CurrentSemanticValue = valueStack.TopElement();
                    //  Default action "@$ = @1.Merge(@N)" for location info.
                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
                    TSpan atN = LocationStack[LocationStack.Depth - 1];
                    CurrentLocationSpan =
                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
                }
            }

            DoAction(ruleNumber);

            for (int i = 0; i < rule.RightHandSide.Length; i++)
            {
                StateStack.Pop();
                valueStack.Pop();
                LocationStack.Pop();
            }
            FsaState = StateStack.TopElement();

            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
            {
                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
            }

            StateStack.Push(FsaState);
            valueStack.Push(CurrentSemanticValue);
            LocationStack.Push(CurrentLocationSpan);
        }
        private void Reduce(int ruleNumber)
        {
#if TRACE_ACTIONS
            DisplayRule(ruleNumber);
#endif
            Rule rule = rules[ruleNumber];
            if (rule.RightHandSide.Length == 1)
            {
                CurrentSemanticValue = valueStack.TopElement();
                CurrentLocationSpan  = LocationStack.TopElement();
            }
            else
            {
                if (rule.RightHandSide.Length == 0)
                {
                    CurrentSemanticValue = default(TValue);

                    CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
                                           scanner.yylloc.Merge(LastSpan) :
                                           default(TSpan));
                }
                else
                {
                    CurrentSemanticValue = valueStack.TopElement();

                    TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
                    TSpan atN = LocationStack[LocationStack.Depth - 1];
                    CurrentLocationSpan =
                        ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
                }
            }

            DoAction(ruleNumber);

            for (int i = 0; i < rule.RightHandSide.Length; i++)
            {
                StateStack.Pop();
                valueStack.Pop();
                LocationStack.Pop();
            }

#if TRACE_ACTIONS
            DisplayStack();
#endif
            FsaState = StateStack.TopElement();

            if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
            {
                FsaState = states[FsaState.Goto[rule.LeftHandSide]];
            }

            StateStack.Push(FsaState);
            valueStack.Push(CurrentSemanticValue);
            LocationStack.Push(CurrentLocationSpan);
        }
Beispiel #3
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);
        }