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); }
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); } } } } } ); }
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; }
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); } } } } } ); }
internal bool AddEdge(IProduction symbol, LR0State targetState) { ProductionBase production = symbol as ProductionBase; return m_edges.Add(new LR0Edge(Index, production.Info.Index, targetState.Index)); }
internal bool AddEdge(IProduction symbol, LR0State targetState) { ProductionBase production = symbol as ProductionBase; return(m_edges.Add(new LR0Edge(Index, production.Info.Index, targetState.Index))); }