public void AddRowState(RowState row) { if (!RowStates.Contains(row)) { RowStates.Add(row); } }
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); }
/// <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); }
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))); } } } } }