Пример #1
0
        private bool CheckExist(ISet <LR0Item> set, out LR0State targetState)
        {
            bool exist = false;

            targetState = null;

            foreach (var state in m_states)
            {
                if (set.SetEquals(state.ItemSet))
                {
                    exist       = true;
                    targetState = state;
                    break;
                }
            }

            return(exist);
        }
Пример #2
0
        public void BuildModel()
        {
            ISet<LR0Item> initStateSet = new HashSet<LR0Item>();
            initStateSet.Add(new LR0Item(m_infoManager.GetInfo(m_infoManager.RootProduction).Index, 0));

            initStateSet = GetClosure(initStateSet);

            LR0State initState = new LR0State(initStateSet);
            initState.Index = 0;

            m_states.Add(initState);


            bool isChanged = false;
            List<LR0State> changedStates = new List<LR0State>(m_states);
            List<LR0State> swapList = new List<LR0State>();

            //build shifts and gotos
            do
            {
                isChanged = false;

                //swap lists in different usages
                var states = changedStates;
                changedStates = swapList;
                changedStates.Clear();
                swapList = states;

                Parallel.ForEach(states,
                    /* 
                     * calculate goto/shift of each item set in parallel
                     */
                    state =>
                    {
                        state.PossibleEdges.Clear();

                        foreach (var item in state.ItemSet)
                        {
                            var production = m_infoManager.Productions[item.ProductionIndex];
                            var info = m_infoManager.GetInfo(production);

                            //m_dotSymbolVisitor.DotLocation = item.DotLocation;
                            var symbols = production.Accept(m_dotSymbolVisitor, item.DotLocation);
                            foreach (var symbol in symbols)
                            {
                                if (symbol.IsEos)
                                {
                                    //accept
                                    state.IsAcceptState = true;
                                    continue;
                                }

                                var targetStateSet = GetGoto(state.ItemSet, symbol);

                                state.PossibleEdges.Add(new KeyValuePair<IProduction, ISet<LR0Item>>(symbol, targetStateSet));

                                //calculate lexer states that the current LR0 state should cover
                                if (symbol.IsTerminal && !symbol.IsEos)
                                {
                                    Terminal t = symbol as Terminal;
                                    Token token = t.Token;

                                    state.AddShiftingLexer(token.LexerIndex);
                                }
                            }
                        }
                    }
                );

                foreach (var state in states)
                {

                    foreach (var possibleEdge in state.PossibleEdges)
                    {
                        var symbol = possibleEdge.Key;
                        var targetStateSet = possibleEdge.Value;

                        LR0State targetState;
                        //check if the target state is exist
                        bool exist = CheckExist(targetStateSet, out targetState);

                        if (exist)
                        {
                            //check edges
                            isChanged = state.AddEdge(symbol, targetState) || isChanged;
                        }
                        else
                        {
                            isChanged = true;

                            //create new state
                            targetState = new LR0State(targetStateSet);

                            targetState.Index = m_states.Count;
                            m_states.Add(targetState);

                            //create edge for it
                            state.AddEdge(symbol, targetState);

                            changedStates.Add(targetState);
                        }
                    }
                }

            } while (isChanged);


            //build reduces
            Parallel.ForEach(m_states,
                state =>
                {
                    foreach (var item in state.ItemSet)
                    {
                        var production = m_infoManager.Productions[item.ProductionIndex];
                        var info = m_infoManager.GetInfo(production);

                        if (item.DotLocation == info.SymbolCount)
                        {
                            foreach (var followSymbol in info.Follow)
                            {
                                //reduce
                                state.AddReduce(followSymbol, production);

                                if (!followSymbol.IsEos)
                                {
                                    Terminal t = followSymbol as Terminal;
                                    Token token = t.Token;

                                    state.AddReducingLexer(token.LexerIndex);
                                }
                            }

                        }
                    }
                }
            );
        }
Пример #3
0
        private bool CheckExist(ISet<LR0Item> set, out LR0State targetState)
        {
            bool exist = false;
            targetState = null;

            foreach (var state in m_states)
            {
                if (set.SetEquals(state.ItemSet))
                {
                    exist = true;
                    targetState = state;
                    break;
                }
            }

            return exist;
        }
Пример #4
0
        public void BuildModel()
        {
            ISet <LR0Item> initStateSet = new HashSet <LR0Item>();

            initStateSet.Add(new LR0Item(m_infoManager.GetInfo(m_infoManager.RootProduction).Index, 0));

            initStateSet = GetClosure(initStateSet);

            LR0State initState = new LR0State(initStateSet);

            initState.Index = 0;

            m_states.Add(initState);


            bool            isChanged     = false;
            List <LR0State> changedStates = new List <LR0State>(m_states);
            List <LR0State> swapList      = new List <LR0State>();

            //build shifts and gotos
            do
            {
                isChanged = false;

                //swap lists in different usages
                var states = changedStates;
                changedStates = swapList;
                changedStates.Clear();
                swapList = states;

                Parallel.ForEach(states,

                                 /*
                                  * calculate goto/shift of each item set in parallel
                                  */
                                 state =>
                {
                    state.PossibleEdges.Clear();

                    foreach (var item in state.ItemSet)
                    {
                        var production = m_infoManager.Productions[item.ProductionIndex];
                        var info       = m_infoManager.GetInfo(production);

                        //m_dotSymbolVisitor.DotLocation = item.DotLocation;
                        var symbols = production.Accept(m_dotSymbolVisitor, item.DotLocation);
                        foreach (var symbol in symbols)
                        {
                            if (symbol.IsEos)
                            {
                                //accept
                                state.IsAcceptState = true;
                                continue;
                            }

                            var targetStateSet = GetGoto(state.ItemSet, symbol);

                            state.PossibleEdges.Add(new KeyValuePair <IProduction, ISet <LR0Item> >(symbol, targetStateSet));

                            //calculate lexer states that the current LR0 state should cover
                            if (symbol.IsTerminal && !symbol.IsEos)
                            {
                                Terminal t  = symbol as Terminal;
                                Token token = t.Token;

                                state.AddShiftingLexer(token.LexerIndex);
                            }
                        }
                    }
                }
                                 );

                foreach (var state in states)
                {
                    foreach (var possibleEdge in state.PossibleEdges)
                    {
                        var symbol         = possibleEdge.Key;
                        var targetStateSet = possibleEdge.Value;

                        LR0State targetState;
                        //check if the target state is exist
                        bool exist = CheckExist(targetStateSet, out targetState);

                        if (exist)
                        {
                            //check edges
                            isChanged = state.AddEdge(symbol, targetState) || isChanged;
                        }
                        else
                        {
                            isChanged = true;

                            //create new state
                            targetState = new LR0State(targetStateSet);

                            targetState.Index = m_states.Count;
                            m_states.Add(targetState);

                            //create edge for it
                            state.AddEdge(symbol, targetState);

                            changedStates.Add(targetState);
                        }
                    }
                }
            } while (isChanged);


            //build reduces
            Parallel.ForEach(m_states,
                             state =>
            {
                foreach (var item in state.ItemSet)
                {
                    var production = m_infoManager.Productions[item.ProductionIndex];
                    var info       = m_infoManager.GetInfo(production);

                    if (item.DotLocation == info.SymbolCount)
                    {
                        foreach (var followSymbol in info.Follow)
                        {
                            //reduce
                            state.AddReduce(followSymbol, production);

                            if (!followSymbol.IsEos)
                            {
                                Terminal t  = followSymbol as Terminal;
                                Token token = t.Token;

                                state.AddReducingLexer(token.LexerIndex);
                            }
                        }
                    }
                }
            }
                             );
        }
Пример #5
0
        internal bool AddEdge(IProduction symbol, LR0State targetState)
        {
            ProductionBase production = symbol as ProductionBase;

            return m_edges.Add(new LR0Edge(Index, production.Info.Index, targetState.Index));
        }
Пример #6
0
        internal bool AddEdge(IProduction symbol, LR0State targetState)
        {
            ProductionBase production = symbol as ProductionBase;

            return(m_edges.Add(new LR0Edge(Index, production.Info.Index, targetState.Index)));
        }