예제 #1
0
def dot(category):
    nfa = NFA()
    nfa.classifier = CharClassifier([0])
    nfa.add_state(0)
    nfa.add_state(1)
    nfa.add_transition(0, 1, 1)
    nfa.mark_starting(0)
    nfa.mark_accepting(1, category)
    return nfa
예제 #2
0
def atom(char, category):
    nfa = NFA()
    nfa.classifier = CharClassifier([ord(char), ord(char) + 1])
    nfa.add_state(0)
    nfa.add_state(1)
    nfa.add_transition(0, 1, 1)
    nfa.mark_starting(0)
    nfa.mark_accepting(1, category)
    return nfa
예제 #3
0
def char_set(markers, accept, category):
    nfa = NFA()
    nfa.classifier = CharClassifier(markers)
    nfa.add_state(0)
    nfa.add_state(1)
    for domain in accept:
        nfa.add_transition(0, 1, domain)
    nfa.mark_starting(0)
    nfa.mark_accepting(1, category)
    return nfa
예제 #4
0
    def test_ambiguous_subcons(self):
        nfa = NFA()
        for i in range(1, 7):
            nfa.add_state(i)
        nfa.add_transition(1, 2, 'i')
        nfa.add_transition(2, 3, 'f')
        nfa.add_transition(1, 4, 'i')
        nfa.add_transition(1, 5, 'a')
        nfa.add_transition(1, 6, 'f')
        for i in range(4, 7):
            for char in 'iaf':
                nfa.add_transition(i, i, char)
        nfa.mark_starting(1)
        nfa.mark_accepting(3, 'if')  # if
        for i in range(4, 7):
            nfa.mark_accepting(i, 'id')  # id

        trans_matrix, starting_state, accepting_states = subset_cons(nfa, {'if': CategoryInfo('IF', 0),
                                                                           'id': CategoryInfo('ID', -1)})
        d1 = frozenset({1})
        d2 = frozenset({2, 4})
        d3 = frozenset({3, 4})
        d4 = frozenset({4})
        d5 = frozenset({5})
        d6 = frozenset({6})
        self.assertEqual(trans_matrix,
                         {d1: {'a': d5,
                               'i': d2,
                               'f': d6},
                          d2: {'a': d4,
                               'i': d4,
                               'f': d3},
                          d3: {'a': d4,
                               'i': d4,
                               'f': d4},
                          d4: {'a': d4,
                               'i': d4,
                               'f': d4},
                          d5: {'a': d5,
                               'i': d5,
                               'f': d5},
                          d6: {'a': d6,
                               'i': d6,
                               'f': d6},
                          })
        self.assertEqual(starting_state, d1)
        self.assertEqual(accepting_states, {d2: 'id',
                                            d3: 'if',
                                            d4: 'id',
                                            d5: 'id',
                                            d6: 'id'})
예제 #5
0
def cat(nfa_list):
    nfa_list = list(nfa_list)
    cat_nfa = NFA()
    cat_classifier, class_maps = merge_classifiers(nfa.classifier
                                                   for nfa in nfa_list)
    cat_nfa.classifier = cat_classifier
    for i, z in enumerate(zip(nfa_list, class_maps)):
        nfa, class_map = z  # add everything to cat_nfa
        for start, d in nfa.trans_matrix.items():
            cat_nfa.add_state((i, start))
            for char, end_set in d.items():
                if char == epsilon:
                    for end in end_set:
                        cat_nfa.add_transition((i, start), (i, end), epsilon)
                else:
                    for domain in class_map[char]:
                        for end in end_set:
                            cat_nfa.add_transition((i, start), (i, end),
                                                   domain)
                            # cat_nfa.alphabet |= nfa.alphabet

    for i in range(len(nfa_list) - 1):  # link these nfa
        this = nfa_list[i]
        next_ = nfa_list[i + 1]
        for state in this.accepting_states:
            cat_nfa.add_transition((i, state), (i + 1, next_.starting_state),
                                   epsilon)

    cat_nfa.mark_starting((0, nfa_list[0].starting_state))
    for state, category in nfa_list[-1].accepting_states.items():
        cat_nfa.mark_accepting((len(nfa_list) - 1, state), category)

    return cat_nfa
예제 #6
0
def alt(nfa_list):
    nfa_list = list(nfa_list)
    alt_nfa = NFA()
    alt_classifier, class_maps = merge_classifiers(nfa.classifier
                                                   for nfa in nfa_list)
    alt_nfa.classifier = alt_classifier
    for i, z in enumerate(zip(nfa_list, class_maps)):
        nfa, class_map = z
        for start, d in nfa.trans_matrix.items():
            alt_nfa.add_state((i, start))
            for char, end_set in d.items():
                if char == epsilon:
                    for end in end_set:
                        alt_nfa.add_transition((i, start), (i, end), epsilon)
                else:
                    for domain in class_map[char]:
                        for end in end_set:
                            alt_nfa.add_transition((i, start), (i, end),
                                                   domain)
        # alt_nfa.alphabet |= nfa.alphabet
        for state, category in nfa.accepting_states.items():
            alt_nfa.mark_accepting((i, state), category)

    alt_nfa.add_state(1)  # starting state
    for i, nfa in enumerate(nfa_list):
        alt_nfa.add_transition(1, (i, nfa.starting_state), epsilon)

    alt_nfa.mark_starting(1)

    return alt_nfa
예제 #7
0
def build_nfa1():  # NFA on page 151 of the Dragon Book
    nfa = NFA()
    for i in range(4):
        nfa.add_state(i)
    nfa.add_transition(0, 0, 2)
    nfa.add_transition(0, 1, 1)
    nfa.add_transition(1, 1, 1)
    nfa.add_transition(1, 2, 2)
    nfa.add_transition(2, 1, 1)
    nfa.add_transition(2, 3, 2)
    nfa.add_transition(3, 0, 2)
    nfa.add_transition(3, 1, 1)
    nfa.mark_starting(0)
    nfa.mark_accepting(3, 0)
    nfa.classifier = CharClassifier([ord('a'), ord('b'), ord('b') + 1])
    return nfa
예제 #8
0
def build_test_nfa():  # example NFA on EC pp.51
    nfa = NFA()
    for i in range(10):
        nfa.add_state(i)
    nfa.mark_starting(0)
    nfa.mark_accepting(9, 1)

    nfa.classifier = CharClassifier(
        [ord('a'), ord('b'), ord('c'),
         ord('c') + 1])

    nfa.add_transition(0, 1, 1)
    nfa.add_transition(1, 2, epsilon)
    nfa.add_transition(2, 9, epsilon)
    nfa.add_transition(2, 3, epsilon)
    nfa.add_transition(3, 4, epsilon)
    nfa.add_transition(3, 6, epsilon)
    nfa.add_transition(4, 5, 2)
    nfa.add_transition(5, 8, epsilon)
    nfa.add_transition(6, 7, 3)
    nfa.add_transition(7, 8, epsilon)
    nfa.add_transition(8, 3, epsilon)
    nfa.add_transition(8, 9, epsilon)

    return nfa