Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        // 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);
            }
        }