private void ComputeIncludes() { // (p,A) include (q,B) iff B -> Beta A Gamma and Gamma => empty and q -> Beta -> p foreach (AutomatonState q in states) { foreach (Transition qB in q.nonTerminalTransitions.Values) { foreach (Production prod in qB.A.productions) { for (int i = prod.rhs.Count - 1; i >= 0; i--) { Symbol A = prod.rhs[i]; NonTerminal NT = A as NonTerminal; if (NT != null) { AutomatonState p = PathTo(q, prod, i); p.nonTerminalTransitions[NT].includes.Add(qB); } if (!A.IsNullable()) { break; } } } } } }
internal static void PopulatePrefixes(List <AutomatonState> states) { AutomatonState start = states[0]; start.shortestPrefix = new List <Symbol>(); // The empty list. start.statePath = new List <AutomatonState>(); start.statePath.Add(start); bool changed = false; do { changed = false; foreach (AutomatonState state in states) { List <Symbol> newfix; List <Symbol> prefix = state.shortestPrefix; List <AutomatonState> newPath; List <AutomatonState> oldPath = state.statePath; if (prefix != null) { foreach (KeyValuePair <Symbol, AutomatonState> a in state.Goto) { Symbol smbl = a.Key; AutomatonState nextState = a.Value; newfix = ListClone <Symbol>(prefix); newPath = ListClone <AutomatonState>(oldPath); newPath.Add(nextState); if (!smbl.IsNullable()) { newfix.Add(smbl); } if (nextState.shortestPrefix == null || nextState.shortestPrefix.Count > newfix.Count) { nextState.shortestPrefix = newfix; nextState.statePath = newPath; changed = true; } } } } } while (changed); }