Пример #1
0
        private Tuple <NfaState, NfaState> buildNfa(Exp ast)
        {
            NfaState start    = null;
            NfaState terminal = null;

            if (ast.Type != Exp.ExpType.Concat)
            {
                start    = CreateState();
                terminal = CreateState();
            }

            switch (ast.Type)
            {
            case Exp.ExpType.Token:
            {
                AddEdge(start, terminal, ast.C);
                break;
            }

            case Exp.ExpType.Concat:
            {
                var nfa1 = buildNfa(ast.E1);
                var nfa2 = buildNfa(ast.E2);
                start    = nfa1.Item1;
                terminal = nfa2.Item2;

                AddEdge(nfa1.Item2, nfa2.Item1, EPSILON);
                break;
            }

            case Exp.ExpType.Alter:
            {
                var nfa1 = buildNfa(ast.E1);
                var nfa2 = buildNfa(ast.E2);
                AddEdge(start, nfa1.Item1, EPSILON);
                AddEdge(start, nfa2.Item1, EPSILON);
                AddEdge(nfa1.Item2, terminal, EPSILON);
                AddEdge(nfa2.Item2, terminal, EPSILON);
                break;
            }

            case Exp.ExpType.Kleene:
            {
                var nfa = buildNfa(ast.E1);
                AddEdge(start, terminal, EPSILON);
                AddEdge(start, nfa.Item1, EPSILON);
                AddEdge(nfa.Item2, nfa.Item1, EPSILON);
                AddEdge(nfa.Item2, terminal, EPSILON);
                break;
            }
            }

            return(new Tuple <NfaState, NfaState> (start, terminal));
        }