private Set <int> epsilons(int state, FA fa) { Set <int> eps = new Set <int>(); foreach (Tuple <Trans, int> t in fa.outTrans(state)) { if (t.Item1 is Epsilon) { eps.Add(t.Item2); } } return(eps); }
public FA dfaFromNfa(FA nfa) { Dictionary <Set <int>, Set <Tuple <Trans, Set <int> > > > newTg = new Dictionary <Set <int>, Set <Tuple <Trans, Set <int> > > >(); Set <int> startState = epsilonClosure(nfa.startState, nfa); Set <Set <int> > newAcceptingStates = new Set <Set <int> >(); Stack <Set <int> > workList = new Stack <Set <int> >(); Set <Set <int> > done = new Set <Set <int> >(); workList.Push(startState); while (workList.Count != 0) { Set <int> state = workList.Peek(); workList.Pop(); done.Add(state); List <Tuple <Trans, int> > allOutTrans = new List <Tuple <Trans, int> >(); if (nfa.acceptingStates.intersect(state).Count != 0) { newAcceptingStates.Add(state); } foreach (int s in state) { allOutTrans.AddRange(nfa.outTrans(s)); } Dictionary <Trans, List <Tuple <Trans, int> > > groups = new Dictionary <Trans, List <Tuple <Trans, int> > > (); var _groups = allOutTrans.GroupBy(p => { return(p.Item1); }); foreach (IGrouping <Trans, Tuple <Trans, int> > g in _groups) { groups.Add(g.Key, g.ToList()); } foreach (KeyValuePair <Trans, List <Tuple <Trans, int> > > kv in groups) { // kv -> Tuple<shared_ptr<Trans>, vector<Tuple<shared_ptr<Trans>, int>>> Trans cond = kv.Key; if (!(cond is Epsilon)) { List <int> _states = Utils.list(kv.Value.Select(a => a.Item2)); Set <int> states = Utils.make_set(_states); states = epsilonClosure(states, nfa); Utils.Add(newTg, state, new Tuple <Trans, Set <int> >(cond, states)); if (!done.Contains(states)) { //Utils.printf("found new state: %s", states); workList.Push(states); } } } } LabellerInt <Set <int> > c = new LabellerInt <Set <int> >(); FA dfa = new FA(c.labelFor(startState), -1); foreach (KeyValuePair <Set <int>, Set <Tuple <Trans, Set <int> > > > kv in newTg) { int s = c.labelFor(kv.Key); Set <Tuple <Trans, int> > _trans2 = Utils.make_set(kv.Value.Select(p => { return(new Tuple <Trans, int>(p.Item1, c.labelFor(p.Item2))); })); List <Tuple <Trans, int> > trans2 = Utils.list(_trans2); dfa.tg[s] = trans2; } Set <int> accepting = Utils.make_set(newAcceptingStates.Select(s => { return(c.labelFor(s)); })); dfa.acceptingStates = accepting; return(dfa); }
// Longest match wins // in case of tie, first-in-rule-listing wins public Token nextToken() // throws LexerError { string maxAcceptingRule = ""; int maxAcceptingPos = 0, maxAcLine = -1, maxAcCol = -1; string scope = ""; if (scopes.Count != 0) { scope = scopes.Peek(); } foreach (Tuple <string, FA> kv in dfasByScope[scope]) { string ruleName = kv.Item1; FA fa = kv.Item2; //log("Rule %s, pos=%s", ruleName, pos); int state = fa.startState; int p = pos; int __line = line; int __col = col; while (true) { if (p == inputText.Length) { if (fa.acceptingStates.Contains(state)) { return(accept(ruleName, p, __line, __col)); } else { string ex = "No recognizable token at end of file"; throw new Exception(ex); } } char c = inputText[p]; bool found = false; foreach (Tuple <Trans, int> t in fa.outTrans(state)) { //Utils.printf("....Match %s?", t.a); if (t.Item1.match(c)) { state = t.Item2; found = true; break; } //Utils.printf("....fails"); } if (found) { p++; __col++; if (c == '\n') { __line++; __col = 0; } } else { if (fa.acceptingStates.Contains(state)) { if (p > maxAcceptingPos) { maxAcceptingPos = p; maxAcceptingRule = ruleName; maxAcLine = __line; maxAcCol = __col; goto forRules; } else { goto forRules; } } else { goto forRules; } } } // while forRules :; } // for kv in rules if (maxAcceptingPos > pos) { return(accept(maxAcceptingRule, maxAcceptingPos, maxAcLine, maxAcCol)); } else { if (errorRuleName != "") { int advLine, advCol; advance(pos, line, col, out advLine, out advCol); Token t = accept(errorRuleName, pos + 1, advLine, advCol); return(t); } string ex = "Cannot process input near: " + formatLiteral(Utils.Mid(inputText, pos, 15)) + ""; throw new Exception(ex); } }