def mergeNFAConcat(nfa1 : NFA, nfa2 : NFA):

    # calculam numarul de stari la final
    numarStariTotal = nfa1.numberOfStates + nfa2.numberOfStates
    
    # instantiem un nfa nou
    newNfa = NFA(numarStariTotal)
    
    # setam starea finala ca fiind numar total de stari - 1 (ultima stare din nfa2)
    newNfa.finalStates.append(numarStariTotal - 1)

    # setam tranzitiile
    # adaugam fiecare tranzitie din nfa1 asa cum e
    newNfa.tabelTranzitii = nfa1.tabelTranzitii.copy()

    # adaugam fiecare tranzitie din nfa2 cu starile shiftate
    # facem un map + numarStariNfa1 peste stari
    for (state, simbol), nextState in nfa2.tabelTranzitii.items():
        newNfa.tabelTranzitii[(state + (nfa1.numberOfStates), simbol)] = [i + nfa1.numberOfStates for i in nextState]

    # adaugam "podul (bridge)" intre cele 2 nfa-uri (o tranzitie pe eps)
    # tranzitia este intre starea cu numarul nfa1.numarStari - 1 si nf1.numarStari
    try:
        newNfa.tabelTranzitii[(nfa1.numberOfStates - 1, "eps")] = newNfa.tabelTranzitii[(nfa1.numberOfStates - 1, "eps")] + [nfa1.numberOfStates]
    except:
        newNfa.tabelTranzitii[(nfa1.numberOfStates - 1, "eps")] = [nfa1.numberOfStates]

    # print("concat")
    # print(newNfa)
    # print()

    return newNfa
Exemple #2
0
    def test_parse_rg(self):
        a = NFA.from_rg(parse_rg("S -> aS | bB \n B -> cS | f"))
        self.assertTrue(a.accepts('aaaaabcaaaabf'))
        self.assertTrue(a.accepts('bf'))
        self.assertTrue(a.accepts('bcaaaabf'))
        self.assertTrue(a.accepts('abcabcabcabf'))
        self.assertFalse(a.accepts('bcf'))
        self.assertFalse(a.accepts('aaaacf'))
        self.assertFalse(a.accepts(''))

        a = NFA.from_rg(parse_rg("S -> a | cB | & \n B -> f"))
        self.assertTrue(a.accepts('a'))
        self.assertTrue(a.accepts('cf'))
        self.assertTrue(a.accepts(''))
        self.assertFalse(a.accepts('c'))
        self.assertFalse(a.accepts('f'))
        self.assertFalse(a.accepts('acf'))

        a = NFA.from_rg(parse_rg("S -> a \n S -> cB | & \n B -> f"))
        self.assertTrue(a.accepts('a'))
        self.assertTrue(a.accepts('cf'))
        self.assertTrue(a.accepts(''))
        self.assertFalse(a.accepts('c'))
        self.assertFalse(a.accepts('f'))
        self.assertFalse(a.accepts('acf'))

        a = NFA.from_rg(parse_rg("Start -> fZ \n Z -> zZ | yZ | z"))
        self.assertTrue(a.accepts('fyz'))
        self.assertTrue(a.accepts('fz'))
        self.assertTrue(a.accepts('fzzyyzz'))
        self.assertFalse(a.accepts('z'))
        self.assertFalse(a.accepts('fzzzy'))
        self.assertFalse(a.accepts(''))
Exemple #3
0
    def testEmptyClosure(self):
        nfa = NFA('01')

        s0 = nfa.new_state(initial=True)

        closure = nfa.closure(s0)
        self.assertIn(s0, closure, "Closure start state should be in closure")
Exemple #4
0
def kleene(nfa1):
    initial_state, final_state = new_states(nfa1)

    nfa = NFA(CHARSET, {initial_state, final_state}, initial_state, {final_state}, {})

    for state in nfa1.states:
        nfa.states.add(state)

    new_delta = {}

    for (state, symbol), next_states in nfa1.delta.items():
        new_delta.update({(state, symbol): next_states})

    for stop_state in nfa1.final_states:
        if (stop_state, "") in nfa1.delta:
            new_next_states = nfa1.delta[(stop_state, "")]
            new_next_states.add(final_state)
            new_delta.update({(stop_state, ""): new_next_states})
        else:
            new_delta.update({(stop_state, ""): {final_state}})

    new_delta.update({(initial_state, ""): {nfa1.start_state, final_state}})
    new_delta.update({(final_state, ""): {initial_state}})

    nfa.delta = new_delta
  
    return nfa
Exemple #5
0
    def concatenate_nfa(self, nfa: NFA, char_to_concatenate: str) -> NFA:
        """
        concatenate_nfa
        Concatenate a regex char to an existing NFA.

        :param nfa: The existing NFA.
        :param char_to_concatenate: Character from regex to concatenate.
        :return: The resulting NFA.
        """

        # As states are added, update the last state to connect from
        # if this isn't the first char of the regex (only a start state), add an epsilon transition.
        if len(nfa.states) > 1:
            self.last_state = nfa.add_epsilon_connector(self.last_state)

        # add the last state as an last close group
        self.last_closed_group = self.last_state

        # Connect to to new state on concat_char
        if self.union_in_progress:
            self.last_state = nfa.add_normal_char(
                self.last_state, char_to_concatenate, True,
                self.union_in_progress[-1][1])
        elif self.last_star:
            self.last_state = nfa.add_normal_char(self.last_state,
                                                  char_to_concatenate, True,
                                                  self.last_star[-1])
            self.last_star = self.last_star[:-1]

        else:
            self.last_state = nfa.add_normal_char(self.last_state,
                                                  char_to_concatenate, True,
                                                  self.open_groups[-1])

        return nfa
  def test_cat(self):
    a = NFA.build_a('a')
    b = NFA.build_a('b')
    ab = NFA.build_cat(a, b)

    self.assert_(ab.initial)
    self.assert_(ab.finals)
Exemple #7
0
def synchro_prod_poly_example():
    A = NFA.spec("""
        0
        1
        0 a 1 c 1
        1 a 0""").named("A").visu()

    B = NFA.spec("""
        0
        1
        0 b 1 c 1
        1 b 0""").renum(2).named("B").visu()

    _ = NFA.Stay
    C = NFA.sprod(A, B, svec={("a", _), (_, "b"),
                              ("c", "c")}).visu()  # .texvisu(renum=True)

    D = A | B | C
    D.visu().texvisu(renum=True,
                     at={
                         '0': (0, .5),
                         '1': (1, .5),
                         '2': (-.5, 0),
                         '3': (-.5, -1),
                         '(0, 2)': (0, 0),
                         '(1, 2)': (1, 0),
                         '(0, 3)': (0, -1),
                         '(1, 3)': (1, -1),
                     }.get,
                     params=",x=3cm,y=3cm")
Exemple #8
0
 def runTest(self):
     #nfa = NFA(t3_29)
     nfa = NFA(*load_default('t3_30'))
     self.assertTrue(SimNFA(nfa, "aabb"))
     try:
         nfa.draw()
     except:
         pass
class TestNFA(unittest.TestCase):
  def setUp(self):
    self.dg = {
          0: {'': [1, 7],},
          1: {'': [2, 4],},
          2: {'a': [3,]},
          3: {'': [6,], },
          4: {'b': [5,], },
          5: {'': [6,], },
          6: {'': [1, 7,], },
          7: {'a': [8,], },
          8: {'b': [9,], },
          9: {'b': [10,], },
          10: {}
    }
        
    self.nfa = NFA(self.dg, 0, frozenset([10]))

  def test_eclosure_0(self):
    given = frozenset((0,))
    expected = frozenset((0, 1, 2, 4, 7))
    self.assertEqual(self.nfa.eclosure(given), expected)

  def test_eclosure_2(self):
    given = frozenset((2,))
    expected = frozenset((2,))
    self.assertEqual(self.nfa.eclosure(given), expected)

  def test_move_2_3(self):
    given = frozenset((2,))
    expected = frozenset((3,))
    self.assertEqual(self.nfa.move(given, 'a'), expected)

  def test_move_6_8(self):
    given = frozenset((6,))
    expected = frozenset((3, 8,))
    self.assertEqual(self.nfa.move(given, 'a'), expected)
    
  def test_makeDFA(self):
    '''
      from p143
    '''
    A = frozenset([0, 1, 2, 4, 7])
    B = frozenset([1, 2, 3, 4, 6, 7, 8])
    C = frozenset([1, 2, 4, 5, 6, 7])
    D = frozenset([1, 2, 4, 5, 6, 7, 9])
    E = frozenset([1, 2, 4, 5, 6, 7, 10])

    expected = {
      A: {'a': B, 'b': C},
      B: {'a': B, 'b': D},
      C: {'a': B, 'b': C},
      D: {'a': B, 'b': E},
      E: {'a': B, 'b': C},
    }
    self.assertEqual(self.nfa.makeDFA(), expected)
Exemple #10
0
def main():
    input_string = readFile("testcasesUnix/nfa6.txt")

    nfa = NFA()
    nfa.initNFA(input_string)

    dfa = DFA()
    dfa.convertFromNfa(nfa)
    text_file = dfa.makeTextFile()

    dfa_input = readFile("testcasesUnix/dfa6Input.txt")
    dfa.simulateDFA(text_file, dfa_input)
Exemple #11
0
def revision_interro():
    NFA.spec("""
    1
    2
    1 a 1 a 2 b 2 eps 3
    2 b 2
    3 a 3
    """,
             name="Révision ε-removal").visu().rm_eps().visu().dfa().visu(
             ).mini().visu()

    NFA({1}, {3}, {(1, "a", 2), (2, "b", 3), (3, "c", 2), (3, '', 1)},
        name="ε2").visu().rm_eps().visu().dfa().visu().mini().visu()
Exemple #12
0
    def toDFA(self):
        """
        1. convert all rules S -> aT to S (->a) T
        2. convert all rules U -> a  to U (->a) ((qf))
        """
        from nfa import NFA, NDTransitionFunction

        def getAlphabet():
            return {path[0] for key in self for path in self[key]}

        Q = list(self)

        δ = NDTransitionFunction(getAlphabet())
        for source in self:
            for path in self[source]:
                letter, *target = tuple(path)

                if target:
                    δ[source, letter] = target[0]
                else:
                    δ[source, letter] = "qf"
                    if "qf" not in Q:
                        Q.append("qf")

        return NFA(Q, getAlphabet(), δ, "S", {"qf"})
Exemple #13
0
def concat(nfa1: NFA, nfa2: NFA) -> NFA:
    return NFA(states=nfa1.states + nfa2.states,
               starting_state=nfa1.starting_state,
               accepting_states=nfa2.accepting_states,
               transitions=nfa1.transitions + nfa2.transitions +
               [(accepting, "", nfa2.starting_state)
                for accepting in nfa1.accepting_states])
Exemple #14
0
def regex_to_nfa(inp):
    # Takes an regex as input (inp) and returns an epsilon-NFA corresponding to the same regex
    # Used logic and parsers from AutomataTheory.py
    nfaObj = NFAfromRegex(inp)
    nfa = nfaObj.getNFA()
    transitions = {}
    for fromstate, tostates in nfa.transitions.items():
        for state in tostates:
            for char in tostates[state]:
                ch = char
                if (char == ":e:"):
                    ch = 'eps'
                if ch in transitions:
                    if (fromstate - 1) in transitions[ch]:
                        transitions[ch][fromstate -
                                        1] = (transitions[ch][fromstate - 1] +
                                              [state - 1])
                    else:
                        transitions[ch][fromstate - 1] = [state - 1]
                else:
                    transitions[ch] = {(fromstate - 1): [state - 1]}
    sigma = [x for x in nfa.language]
    startstate = nfa.startstate - 1
    finalstates = [x - 1 for x in nfa.finalstates]
    return NFA(len(nfa.states), sigma, transitions, finalstates, startstate)
Exemple #15
0
def main():
    regular = parse_regular_expression("(a)")
    print(regular)
    print(NFA(regular))
    print(NoEpsilonNFA(regular))
    print(DFA(regular))
    print(MinDFA(regular))
Exemple #16
0
def test(pattern, path, count):
  print 'fnmatch(%s, %s) %d times...' % (path, pattern, count)
  start_compile = datetime.now()
  compiled = Compiled(DFA(NFA.fnmatch(pattern)))
  compiled.optimize() # slow!
  end_compile = datetime.now()

  start_execution = datetime.now()
  for x in range(count):
    compiled(path)
  end_execution = datetime.now()

  native_test = compile_native_test(compiled, pattern, path, count)

  start_native = datetime.now()
  native_test()
  end_native = datetime.now()

  from fnmatch import fnmatch

  start_builtin = datetime.now()
  for x in range(count):
    fnmatch(path, pattern)
  end_builtin = datetime.now()

  return {
    'pattern': pattern,
    'path': path,
    'count': count,
    'compile_time': (end_compile-start_compile),
    'execution_time': (end_execution-start_execution),
    'native_time': (end_native-start_native),
    'builtin_time': (end_builtin-start_builtin),
  }
Exemple #17
0
def minimisation_exo():
    NFA.spec(
        """
    a
    c f g
    
    a 0 b 1 e
    b 0 b 1 c
    e 0 e 1 f
    f 1 c 0 b
    c 1 f 0 e
    d 0 c 1 g
    g 0 d 1 f
    """,
        name="Minimisation exo",
        Qtype=str).visu().trim().visu().dfa().visu().mini(table=False).visu()
Exemple #18
0
def alternate(nfa1, nfa2):
    rename_states(nfa2, nfa1)
    initial_state, final_state = new_states(nfa1, nfa2)
  
    nfa = NFA(CHARSET, {initial_state, final_state}, initial_state, {final_state}, {})

    for state in nfa1.states:
        nfa.states.add(state)
  
    for state in nfa2.states:
        nfa.states.add(state)
  
    new_delta = {}
    new_delta.update({(initial_state, ""): {nfa1.start_state, nfa2.start_state}})

    for stop_state in nfa1.final_states:
        if (stop_state, "") in nfa1.delta:
            new_next_states = nfa1.delta[(stop_state, "")]
            new_next_states.add(final_state)
            new_delta.update({(stop_state, ""): new_next_states})
        else:
            new_delta.update({(stop_state, ""): {final_state}})
  
    for stop_state in nfa2.final_states:
        if (stop_state, "") in nfa2.delta:
            new_next_states = nfa2.delta[(stop_state, "")]
            new_next_states.add(final_state)
            new_delta.update({(stop_state, ""): new_next_states})
        else:
            new_delta.update({(stop_state, ""): {final_state}})

    for (state, symbol), next_states in nfa1.delta.items():
        if state in nfa1.final_states and symbol == "":
            pass

        new_delta.update({(state, symbol): next_states})
  
    for (state, symbol), next_states in nfa2.delta.items():
        if state in nfa1.final_states and symbol == "":
            pass

        new_delta.update({(state, symbol): next_states})
  
    nfa.delta = new_delta
  
    return nfa
def ast_to_nfa(ast):
	"""Convert an AST to an NFA.

	"""
	(initial, accepting) = ast._thompson()
	accepting.accepting = 1

	return NFA(initial)
Exemple #20
0
def rm_esp_clos_test():
    A = NFA.spec("""
    0
    2
    0 eps 1
    1 eps 2
    2 a 0
    """).visu().rm_eps().visu()
Exemple #21
0
def union(nfa1: NFA, nfa2: NFA) -> NFA:
    starting = next(name_generator)
    return NFA(states=nfa1.states + nfa2.states + [starting],
               starting_state=starting,
               accepting_states=nfa1.accepting_states + nfa2.accepting_states,
               transitions=nfa1.transitions + nfa2.transitions +
               [(starting, "", nfa1.starting_state),
                (starting, "", nfa2.starting_state)])
Exemple #22
0
def verif_mini_prog():
    prog = NFA.spec("""
    1
    __
    1 b=1 1 b=0 2
    2 b:=1 3
    3 proc() 4
    4 b:=0 1""").visu().texvisu("1 > 2 > 3 > 4", "4 < 1")
Exemple #23
0
def Character(c):
    return NFA(
        num_states=2,
        start_state=0,
        end_states=[1],
        transitions={
            0: [(c, 1)]
        })
Exemple #24
0
def interro201819():
    A = NFA.spec("""
    0
    5
    
    0 a 1 c 2
    1 b 1 a 3
    2 b 2 a 4
    3 c 3 a 5 a 2
    4 c 3 a 5 a 1
    """,
                 name="interro2018-2019").visu()
    # A.table()
    A.texvisu("0 / 1 > 3\n 0 \ 2 > 4 / 5", "3 ns,c 2 4 ne,c 1 2 lb 2")
    A = A.dfa().visu().texvisu(renum=True)

    A.mini().visu().texvisu(renum=True)

    B = NFA.spec("""
    eps
    fi
    eps a a c c
    a b ab a aa
    c b cb a ca
    ab a aba b ab
    cb a cba b cb
    aba c ac
    aa c ac a fi
    ca a fi c ac
    cba a fi c ac
    ac c ac a fi
    """,
                 name="StudentMini").visu().mini().visu()

    C = NFA.spec("""
    I
    IV
    I a II c II
    II b II a III
    III c III a IV
    """,
                 name="RealMini").visu()

    (C - B).visu().mini().visu()
    (C | B).visu()
 def test_Empty(self):
   emp = NFA.build_empty()
   self.assert_(emp.initial)
   self.assert_(emp.finals)
   self.assertEqual(len(emp.states) , 2)
   self.assertEqual(
     emp.states[emp.initial],
     dict({'': emp.finals})
   )
Exemple #26
0
 def runTest(self):
     nfa = NFA(*load_default('t3_30'))
     dfa = DFA.from_nfa(nfa)
     #print ("dfa:", dfa.start, dfa.accepts)
     self.assertTrue(SimDFA(dfa, "aabb"))
     try:
         dfa.draw()
     except:
         pass
Exemple #27
0
def re_to_nfa(re):
    if (re.type == RE_EMPTY_SET):
        return NFA(CHARSET, {0}, 0, {}, {})
    
    if (re.type == RE_EMPTY_STRING):
        return NFA(CHARSET, {0}, 0, {0}, {})
    
    if (re.type == RE_SYMBOL):
        return NFA(CHARSET, {0, 1}, 0, {1}, {(0, re.symbol): {1}})
    
    if (re.type == RE_STAR):
        return kleene(re_to_nfa(re.lhs))
    
    if (re.type == RE_CONCATENATION):
        return concat(re_to_nfa(re.lhs), re_to_nfa(re.rhs))
    
    if (re.type == RE_ALTERNATION):
        return alternate(re_to_nfa(re.lhs), re_to_nfa(re.rhs))
Exemple #28
0
 def runTest(self):
     n = NFA(*load_default('t3_30'))
     d = DFA.from_nfa(n)
     print("table:", d.table)
     self.assertDictEqual(d.table, {'A': {'a': ['A'], 'b': ['A']}})
     try:
         d.draw()
     except:
         pass
Exemple #29
0
def symbol_2_nfa(symbol: str) -> NFA:
    start = next(name_generator)
    accept = next(name_generator)
    return NFA(
        states=[start, accept],
        transitions=[(start, symbol, accept)],
        starting_state=start,
        accepting_states=[accept],
    )
 def test_a(self):
   a = NFA.build_a('a')
   self.assert_(a.initial)
   self.assert_(a.finals)
   self.assertEqual(len(a.states) , 2)
   self.assertEqual(
     a.states[a.initial],
     dict({'a': a.finals})
   )
Exemple #31
0
def star(nfa: NFA) -> NFA:
    starting = next(name_generator)
    return NFA(states=nfa.states + [starting],
               starting_state=starting,
               accepting_states=nfa.accepting_states + [starting],
               transitions=nfa.transitions +
               [(starting, "", nfa.starting_state)] +
               [(accepting, "", nfa.starting_state)
                for accepting in nfa.accepting_states])
 def result(self):
   if len(self._result) == 1:
     return self._result[0]
   elif len(self._result) == 0:
     return NFA.build_empty()
   else:
     print 'got multiple nfas?!'
     for n in self._result:
       print n, n.states
     assert False
Exemple #33
0
def exam2020():
    A = NFA.spec("""
    1 2
    1
    1 a 1 b 2
    2 a 3 b 2
    3 a 3 b 1""").visu()
    A.texvisu()
    A.texvisu("1 _ 2 > 3", "1 la 1 2 lb 2 3 la 3 3 ~ 1")
    A.dfa().visu().mini().visu()
Exemple #34
0
 def test5(self):
     n5 = NFA(["A", "B", "C"], ["0", "1"], self.d5, "A", ["C"])
     assert ([
         ('A', [('0', 'A'), ('0', 'B'), ('1', 'A')], False),
         ('B', [('0', 'C'), ('1', 'C')], False), ('C', [], True)
     ] == [
         state for state in map(
             lambda state: (state.value, state.transitions, state.accepted),
             n5.states)
     ])
Exemple #35
0
    def get_nfa(self, idgenerator):
        start = idgenerator.nextID()
        nfa_v = NFA().startState(start)

        cur_state = nfa_v.start
        for c in self.childs:
            if isinstance(c, Primitive):
                next_state = idgenerator.nextID()
                nfa_v.addTransitions(cur_state, c.text(), next_state)
                cur_state = next_state

            else:
                sub_nfa = c.get_nfa(idgenerator)
                nfa_v.addTransitions(cur_state, EPSILON, sub_nfa.start)
                cur_state = sub_nfa.accept
                nfa_v.addSingle(sub_nfa)

        nfa_v.acceptState(cur_state)
        return nfa_v
def mergeNFAOR(nfa1 : NFA, nfa2 : NFA):
    
    # calculam numarul de stari la final
    numarStariTotal = nfa1.numberOfStates + nfa2.numberOfStates + 2
    
    # instantiem un nfa nou
    newNfa = NFA(numarStariTotal)
    
    # setam starea finala ca fiind numar total de stari - 1 (ultima stare din nfa2)
    newNfa.finalStates.append(numarStariTotal - 1)

    # setam tranzitiile
    # adaugam fiecare tranzitie din nfa1 cu stare +1
    for (state, simbol), nextState in nfa1.tabelTranzitii.items():
        newNfa.tabelTranzitii[(state + 1, simbol)] = [i + 1 for i in nextState]

    # adaugam fiecare tranzitie din nfa2 cu starile shiftate
    # facem un map + numarStariNfa1 peste stari
    for (state, simbol), nextState in nfa2.tabelTranzitii.items():
        newNfa.tabelTranzitii[(state + nfa1.numberOfStates + 1, simbol)] = [i + nfa1.numberOfStates + 1 for i in nextState]

    # adaugam tranzitii de pe starile ajutatoare la cele 2 nfa-uri

    # de pe 0 pe cele 2 nfa-uri
    newNfa.tabelTranzitii[(0, "eps")] = [nfa1.numberOfStates + 1, 1]

    # de pe starile finale ale celor 2 nfa-uri pe finala
    try:
        newNfa.tabelTranzitii[(nfa1.numberOfStates, "eps")] = newNfa.tabelTranzitii[(nfa1.numberOfStates, "eps")] + [newNfa.numberOfStates - 1]
    except:
        newNfa.tabelTranzitii[(nfa1.numberOfStates, "eps")] = [newNfa.numberOfStates - 1]

    try:
        newNfa.tabelTranzitii[(newNfa.numberOfStates - 2, "eps")] = newNfa.tabelTranzitii[(newNfa.numberOfStates - 2, "eps")] + [newNfa.numberOfStates - 1] 
    except:
        newNfa.tabelTranzitii[(newNfa.numberOfStates - 2, "eps")] = [newNfa.numberOfStates - 1] 

    # print("or")
    # print(newNfa)
    # print()

    return newNfa
	def to_nfa(self, accepting_id=1):
		"""Convert this AST to an NFA.

		Arguments:
		accepting_id -- The ID of the accepting state (defaults to 1)

		"""

		(initial, accepting) = self._thompson()
		accepting.accepting = accepting_id
		return NFA(initial)
class RegexMatcher(object):
    """ A basic regex parser for ascii characters -- initialize with a
        pattern passed to either the class constructor or set_pattern
        
        Use match* functions to find matches in input strings
    """
    def __init__(self, pattern):
        self.setPattern(pattern)
        # pass

# generates the state machine for the regex specified by pattern
    def setPattern(self, pattern):
        self.pattern = pattern
        self.stateMachine = NFA(pattern)

    def findLongestMatch(self, inStr, i):
        self.stateMachine.reset()
        j = i
        prevFinishedIndex = -1
        while j < len(inStr) and self.stateMachine.advanceStates(inStr[j]):
            j += 1
            if self.stateMachine.finished():
                prevFinishedIndex = j

        if prevFinishedIndex != -1:
            return inStr[i:prevFinishedIndex]
        else:
            return ""

# returns a tuple of (int, str) that contains the integer of the index
# of the first char matching the pattern in input string and the str that
# matches the pattern
# if no match if found, returns a () empty tuple
    def matchFirst(self, inStr, searchStart=0):
        self.stateMachine.reset()
        for i in range(searchStart, len(inStr)):
            match = self.findLongestMatch(inStr, i)
            if match:
                return (i, match)
            
        return ()

# same as matchFirst, except returns a list of all (int, str)
# pairs that match the pattern sent to set_pattern
# if no matches returns []
    def matchAll(self, inStr):
        result = []
        prevMatch = self.matchFirst(inStr, 0)
        while prevMatch:
            result.append(prevMatch)
            startIndex, match = prevMatch
            iOfLastMatch = startIndex + len(match)
            prevMatch = self.matchFirst(inStr, iOfLastMatch)

        return result

    def __str__(self):
        return self.pattern + "\n" + str(self.stateMachine)
 def setUp(self):
   self.dg = {
         0: {'': [1, 7],},
         1: {'': [2, 4],},
         2: {'a': [3,]},
         3: {'': [6,], },
         4: {'b': [5,], },
         5: {'': [6,], },
         6: {'': [1, 7,], },
         7: {'a': [8,], },
         8: {'b': [9,], },
         9: {'b': [10,], },
         10: {}
   }
       
   self.nfa = NFA(self.dg, 0, frozenset([10]))
 def test_zom(self):
   a = NFA.build_a('a')
   azom = NFA.build_zom(a)
 
   self.assert_(azom.initial)
   self.assert_(azom.finals)
Exemple #41
0
 def setUp(self):
     self.fa = NFA('012')
 def Cat(self, t):
   b = self.pop()
   a = self.pop()
   ab = NFA.build_cat(a, b)
   self.push(ab)
 def ZOM(self, Ns):
   a = self.pop()
   azom = NFA.build_zom(a)
   self.push(azom)
 def setPattern(self, pattern):
     self.pattern = pattern
     self.stateMachine = NFA(pattern)
Exemple #45
0
class TestSimpleDFA(unittest.TestCase):
    def setUp(self):
        self.fa = NFA('012')

    def test_instantiation(self):
        self.assertFalse(self.fa.no_of_states, 'States not empty at start')

    def test_add_state(self):
        """Newly created state should not have any transitions"""
        sid = self.fa.new_state()
        for s, p in self.fa.get_edges_from_state(sid).items():
            self.assertFalse(p, 'Found edge ({}, {}) in newly added state {}'.format(s, p, sid))

    def test_edge(self):
        fa = self.fa
        sid = fa.new_state()
        fa.new_edge(sid, '0', sid)
        edges = fa.get_edges_from_state(sid)
        q = edges['0']
        self.assertTrue(sid in q, 'Expected edge not found in {} for state {}'.format(q, sid))
        self.assertTrue(q - {sid} == set(), 'Unexpected edges found in {} for state {}'.format(q, sid))

    def test_has_edge(self):
        fa = self.fa
        s0 = fa.new_state()
        s1 = fa.new_state()
        s2 = fa.new_state()
        self.assertFalse(fa.has_edge(s0, s0), 'Should not have an edge s0->s0')
        self.assertFalse(fa.has_edge(s0, s1), 'Should not have an edge s0->s1')
        self.assertFalse(fa.has_edge(s0, s2), 'Should not have an edge s0->s2')
        self.assertFalse(fa.has_edge(s1, s1), 'Should not have an edge s1->s1')
        self.assertFalse(fa.has_edge(s1, s2), 'Should not have an edge s1->s2')
        self.assertFalse(fa.has_edge(s1, s0), 'Should not have an edge s1->s0')
        self.assertFalse(fa.has_edge(s2, s2), 'Should not have an edge s2->s2')
        self.assertFalse(fa.has_edge(s2, s1), 'Should not have an edge s2->s1')
        self.assertFalse(fa.has_edge(s2, s0), 'Should not have an edge s2->s0')

        fa.new_edge(s0, '0', s1)
        self.assertFalse(fa.has_edge(s0, s0), 'Should not have an edge s0->s0')
        self.assertTrue(fa.has_edge(s0, s1), 'Should have an edge s0->s1')
        self.assertFalse(fa.has_edge(s0, s2), 'Should not have an edge s0->s2')
        self.assertFalse(fa.has_edge(s1, s1), 'Should not have an edge s1->s1')
        self.assertFalse(fa.has_edge(s1, s2), 'Should not have an edge s1->s2')
        self.assertFalse(fa.has_edge(s1, s0), 'Should not have an edge s1->s0')
        self.assertFalse(fa.has_edge(s2, s2), 'Should not have an edge s2->s2')
        self.assertFalse(fa.has_edge(s2, s1), 'Should not have an edge s2->s1')
        self.assertFalse(fa.has_edge(s2, s0), 'Should not have an edge s2->s0')
        fa.new_edge(s0, '1', s2)
        self.assertFalse(fa.has_edge(s0, s0), 'Should not have an edge s0->s0')
        self.assertTrue(fa.has_edge(s0, s1), 'Should have an edge s0->s1')
        self.assertTrue(fa.has_edge(s0, s2), 'Should have an edge s0->s2')
        self.assertFalse(fa.has_edge(s1, s1), 'Should not have an edge s1->s1')
        self.assertFalse(fa.has_edge(s1, s2), 'Should not have an edge s1->s2')
        self.assertFalse(fa.has_edge(s1, s0), 'Should not have an edge s1->s0')
        self.assertFalse(fa.has_edge(s2, s2), 'Should not have an edge s2->s2')
        self.assertFalse(fa.has_edge(s2, s1), 'Should not have an edge s2->s1')
        self.assertFalse(fa.has_edge(s2, s0), 'Should not have an edge s2->s0')
        fa.new_edge(s0, '1', s0)
        self.assertTrue(fa.has_edge(s0, s0), 'Should have an edge s0->s0')
        self.assertTrue(fa.has_edge(s0, s1), 'Should have an edge s0->s1')
        self.assertTrue(fa.has_edge(s0, s2), 'Should have an edge s0->s2')
        self.assertFalse(fa.has_edge(s1, s1), 'Should not have an edge s1->s1')
        self.assertFalse(fa.has_edge(s1, s2), 'Should not have an edge s1->s2')
        self.assertFalse(fa.has_edge(s1, s0), 'Should not have an edge s1->s0')
        self.assertFalse(fa.has_edge(s2, s2), 'Should not have an edge s2->s2')
        self.assertFalse(fa.has_edge(s2, s1), 'Should not have an edge s2->s1')
        self.assertFalse(fa.has_edge(s2, s0), 'Should not have an edge s2->s0')
        fa.new_edge(s1, '0', s1)
        fa.new_edge(s1, '1', s0)
        fa.new_edge(s1, '1', s2)
        fa.new_edge(s2, '0', s0)
        self.assertTrue(fa.has_edge(s0, s0), 'Should have an edge s0->s0')
        self.assertTrue(fa.has_edge(s0, s1), 'Should have an edge s0->s1')
        self.assertTrue(fa.has_edge(s0, s2), 'Should have an edge s0->s2')
        self.assertTrue(fa.has_edge(s1, s1), 'Should have an edge s1->s1')
        self.assertTrue(fa.has_edge(s1, s2), 'Should have an edge s1->s2')
        self.assertTrue(fa.has_edge(s1, s0), 'Should have an edge s1->s0')
        self.assertFalse(fa.has_edge(s2, s2), 'Should not have an edge s2->s2')
        self.assertFalse(fa.has_edge(s2, s1), 'Should not have an edge s2->s1')
        self.assertTrue(fa.has_edge(s2, s0), 'Should have an edge s2->s0')

    def test_del_state(self):
        """Deleting a state should remove all edges to that state"""
        fa = self.fa
        s0 = fa.new_state()
        s1 = fa.new_state()
        s2 = fa.new_state()
        fa.new_edge(s0, '0', s1)
        fa.new_edge(s0, '1', s0)
        fa.new_edge(s0, '1', s2)
        fa.new_edge(s1, '0', s1)
        fa.new_edge(s1, '1', s0)
        fa.new_edge(s1, '1', s2)
        fa.new_edge(s2, '0', s0)

        fa.del_state(s0)
        self.assertEqual(fa.no_of_states, 2, 'Wrong number of states after delete ({})'.format(fa.no_of_states))
        edges = fa.get_edges_from_state(s1)
        self.assertFalse(s0 in [q for q in edges.values()], 'State {} remains a destination after delete')
        self.assertTrue(fa.has_edge_on_symbol(s1, '1', s2), 'Transition s1->s2 over 1 was deleted')
        self.assertFalse(fa.has_edge_on_symbol(s2, '0', s0), 'Transition s2->s0 over 1 not removed by delete')

    def test_process(self):
        fa = self.fa
        s0 = fa.new_state(initial=True, final=True)
        s1 = fa.new_state()

        fa.new_edge(s0, '0', s0)
        fa.new_edge(s0, '1', s1)
        fa.new_edge(s1, '0', s1)
        fa.new_edge(s1, '1', s0)

        vectors = {
            'accepting': [
                '0',
                '00',
                '000',
                '0110',
                '01010',
                '001100',
                '0011',
                '11000000',
                '11',
                '1111',
                '111111'],
            'rejecting': [
                '1',
                '01',
                '001',
                '10',
                '100',
                '111',
                '11111',
                '1111111',
            ]
        }

        for v in vectors['accepting']:
            self.assertTrue(fa.test_input(v), 'String "{}" was not accepted as it should'.format(v))

        for v in vectors['rejecting']:
            self.assertFalse(fa.test_input(v), 'String "{}" was not rejected as it should'.format(v))
Exemple #46
0
    def setUp(self):
        """
        Define one NFA a that accept all strings in the regular language '00*1'
        Define a second NFA accepting all string in the regular language '11*0'
        """
        fa = NFA('01')
        sa0 = fa.new_state(initial=True, name='sa0')
        sa1 = fa.new_state(name='sa1')
        sa2 = fa.new_state(final=True, name='sa2')

        fa.new_edge(sa0, '0', sa1)
        fa.new_edge(sa1, '0', sa1)
        fa.new_edge(sa1, '1', sa2)

        self.assertTrue(fa.test_input('01'), 'String "01" not accepted')
        self.assertFalse(fa.test_input('00'), 'String "00" not rejected')

        fb = NFA('01')
        sb0 = fb.new_state(initial=True, name='sb0')
        sb1 = fb.new_state(name='sb1')
        sb2 = fb.new_state(final=True, name='sb2')

        fb.new_edge(sb0, '1', sb1)
        fb.new_edge(sb1, '1', sb1)
        fb.new_edge(sb1, '0', sb2)

        self.assertTrue(fb.test_input('10'), 'String "10" not accepted')
        self.assertFalse(fb.test_input('11'), 'String "11" not rejected')

        self.nfa1 = fa
        self.nfa2 = fb
Exemple #47
0
    def testClosure(self):
        nfa = NFA('01')

        s0 = nfa.new_state(initial=True)
        s1 = nfa.new_state()
        s2 = nfa.new_state()
        s3 = nfa.new_state(final=True)
        s4 = nfa.new_state()

        nfa.new_edge(s0, '0', s1)
        nfa.new_edge(s0, Epsilon, s2)
        nfa.new_edge(s1, '0', s3)
        nfa.new_edge(s1, Epsilon, s4)
        nfa.new_edge(s2, '1', s2)
        nfa.new_edge(s2, Epsilon, s3)

        closure = nfa.closure(s0)
        self.assertIn(s0, closure, "Closure start state s0 should be in closure")
        self.assertNotIn(s1, closure, "State s1 should not be in closure")
        self.assertIn(s2, closure, "State s2 not in closure")
        self.assertIn(s3, closure, "State s3 not in closure")
        self.assertNotIn(s4, closure, "State s4 should not be in closure")
 def Or(self, t):
   b = self.pop()
   a = self.pop()
   ab = NFA.build_or(a, b)
   self.push(ab)
Exemple #49
0
#!/usr/bin/env python

# our code
from dfa import DFA
from nfa import NFA
from compiler import Compiled

# the python implementation
import fnmatch

# run unit self tests
from characterset import test_CharacterSet
test_CharacterSet()
from dfa import test_distinctArcs
test_distinctArcs()

PATTERNS = ('*.txt', '*', '*.*', 'README.*')
PATHS = ('test.c', 'README.txt', 'README')

for pattern in PATTERNS:
  nfa = NFA.fnmatch(pattern)
  dfa = DFA(nfa)
  compiled = Compiled(dfa, debug=False)
  compiled.optimize()
  for path in PATHS:
    expected = fnmatch.fnmatch(path, pattern)
    assert nfa(path) == expected
    assert dfa(path) == expected
    assert compiled(path) == expected

 def alpha(self, t):
   nfa = NFA.build_a(t.raw) #ugh! t.value?
   self.push(nfa)
Exemple #51
0
 def __init__(self):
     NFA.__init__(self)
Exemple #52
0
if __name__ == '__main__':
  from optparse import OptionParser
  op = OptionParser(usage='usage: %prog [options] pattern')
  op.add_option('--dont-optimize', dest='optimize', 
      help='optimize the generated code', 
      action='store_false', default=True)
  op.add_option('--native', dest='native',
      help='generate native assembly rather than LLVM assembly',
      action='store_true', default=False)
      
  (options, args) = op.parse_args()
  if len(args) != 1:
    op.print_help()
  else:
    from nfa import NFA
    from dfa import DFA
    
    dfa = DFA(NFA.fnmatch(args[0]))
    compiled = Compiled(dfa)
    if options.optimize:
      compiled.optimize()
    if options.native:
      from subprocess import Popen, PIPE
      asm = Popen('llvm-as | llc', shell=True, stdin=PIPE, stdout=PIPE)
      asm.stdin.write(str(compiled))
      asm.stdin.close()
      print asm.stdout.read()
    else:
      print compiled