예제 #1
0
 public void AddRowState(RowState row)
 {
     if (!RowStates.Contains(row))
     {
         RowStates.Add(row);
     }
 }
예제 #2
0
        public State CreateNextState(ISymbol symbol)
        {
            State newstate = new State(_preprocessor, _isClr);

            foreach (RowState rowState in RowStates)
            {
                var symbolInPosition = rowState.GetSymbolInPosition();
                if (symbolInPosition != null && symbolInPosition.Equals(symbol))
                {
                    RowState newRowState = rowState.Clone();
                    newRowState.IncrementPosition();
                    newstate.AddRowState(newRowState);
                }
            }
            return(newstate);
        }
예제 #3
0
        /// <summary>
        /// the order is horrible. I did this to support Recursive LL(1) Grammers
        /// Error :Collection was modified.
        /// </summary>
        public void AddClosures()
        {
            bool changed;

            do
            {
                changed = false;
                foreach (RowState state in RowStates.ToList())
                {
                    if (state.GetSymbolInPosition() is Variable variable)
                    {
                        var defaultLookAhead = state.LookAhead;
                        // if there is no B,
                        if (_isClr && state.HasSymbolAfterPosition())
                        {
                            //first (B{PreviousLookAhead})
                            var symbolsAfterPosition = state.GetSymbolsAfterPosition().ToList();
                            //symbolsAfterPosition.AddRange(defaultLookAhead);
                            defaultLookAhead = _preprocessor.FirstSet(new List <IEnumerable <ISymbol> > {
                                symbolsAfterPosition
                            });
                            if (defaultLookAhead.Contains(Terminal.Epsilon))
                            {
                                defaultLookAhead.Remove(Terminal.Epsilon);
                                defaultLookAhead.AddRange(state.LookAhead);
                            }
                        }
                        variable.RuleSet.Definitions
                        .ForEach(rule =>
                        {
                            RowState rowState = new RowState(variable, rule);
                            if (_isClr)
                            {
                                rowState = new RowState(variable, rule, defaultLookAhead);
                            }
                            if (!RowStates.Contains(rowState))
                            {
                                RowStates.Add(rowState);
                                changed = true;
                            }
                        });
                    }
                }
            } while (changed);
        }
예제 #4
0
        public void InitializeAllStates()
        {
            Queue <State> queue = new Queue <State>();

            State firstState = new State(_preprocessor, _isClr);

            foreach (var rule in _grammarRules.HeadVariable.RuleSet.Definitions)
            {
                var rowState = new RowState(_grammarRules.HeadVariable, rule);
                if (_isClr)
                {
                    rowState.LookAhead = new List <Terminal>()
                    {
                        Terminal.EndOfFile
                    }
                }
                ;
                firstState.AddRowState(rowState);
            }
            firstState.AddClosures();
            queue.Enqueue(firstState);
            States.Add(firstState);
            int stateNo = 1;

            while (queue.Count > 0)
            {
                var state = queue.Dequeue();

                //producing new items
                var extractFirstSymbol = state.ExtractFirstSymbol().Distinct();
                foreach (ISymbol symbol in extractFirstSymbol)
                {
                    var nextState = state.CreateNextState(symbol);
                    nextState.AddClosures();
                    if (nextState.RowStates.Count > 0)
                    {
                        nextState.PreviousState     = state;
                        nextState.TransferredSymbol = symbol;

                        //It's right not to add the state
                        if (!States.Contains(nextState))
                        {
                            queue.Enqueue(nextState);
                            nextState.StateId = stateNo;
                            stateNo++;
                            States.Add(nextState);

                            //if it's not the first State
                            if (!state.NextStates.ContainsKey(symbol))
                            {
                                state.NextStates.Add(symbol, nextState);
                            }
                        }
                        else
                        {//but we should add next state to know where to go
                            state.NextStates.Add(symbol, States.First(f => f.Equals(nextState)));
                        }
                    }
                }
            }
        }