Exemplo n.º 1
0
def do(SM):
    """Creates a state machine that matches the reverse of what 'SM' matches.
    """
    result = StateMachine(InitStateIndex=SM.init_state_index)
    original_acceptance_state_index_list = SM.get_acceptance_state_index_list()

    if len(original_acceptance_state_index_list) == 0:
        # If there is no acceptance state in a state machine, the state machine
        # cannot match any pattern, it is equivalent to '\None'. The reverse
        # of \None is \None.
        return special.get_none()

    # Ensure that each target state index has a state inside the state machine
    for state_index in SM.states.keys():
        result.create_new_state(StateIdx=state_index)

    for state_index, state in SM.states.items():
        for target_state_index, trigger_set in state.target_map.get_map(
        ).items():
            result.states[target_state_index].add_transition(
                trigger_set.clone(), state_index)

        for target_state_index in state.target_map.get_epsilon_target_state_index_list(
        ):
            result.states[
                target_state_index].target_map.add_epsilon_target_state(
                    state_index)

    # -- copy all origins of the original state machine
    # -- We need to cancel any acceptance, because the inverted engine now starts
    #    from a combination of the acceptance states and ends at the initial state.
    for state_index, state in SM.states.items():
        original_origin_list = [origin.clone() for origin in state.origins()]
        for origin in original_origin_list:
            origin.set_input_position_restore_f(False)
            origin.set_pre_context_id(E_PreContextIDs.NONE)
            origin.set_acceptance_f(False)
        result.states[state_index].origins().set(
            original_origin_list)  # deepcopy implicit

    # -- only the ORIGINAL initial state becomes an acceptance state (end of inverse)
    result.states[SM.init_state_index].set_acceptance(True)

    # -- setup an epsilon transition from an new init state to all previous
    #    acceptance states.
    new_init_state_index = result.create_new_init_state()
    for state_index in original_acceptance_state_index_list:
        result.add_epsilon_transition(new_init_state_index, state_index)

    # -- for uniqueness of state ids, clone the result
    return result.clone()
Exemplo n.º 2
0
def do(SM):
    """Creates a state machine that matches the reverse of what 'SM' matches.
    """
    result                               = StateMachine(InitStateIndex=SM.init_state_index)
    original_acceptance_state_index_list = SM.get_acceptance_state_index_list()

    if len(original_acceptance_state_index_list) == 0:
        # If there is no acceptance state in a state machine, the state machine
        # cannot match any pattern, it is equivalent to '\None'. The reverse
        # of \None is \None.
        return special.get_none()
       
    # Ensure that each target state index has a state inside the state machine
    for state_index in SM.states.keys():
        result.create_new_state(StateIdx=state_index)

    for state_index, state in SM.states.items():
        for target_state_index, trigger_set in state.target_map.get_map().items():
            result.states[target_state_index].add_transition(trigger_set.clone(), state_index)

        for target_state_index in state.target_map.get_epsilon_target_state_index_list():
            result.states[target_state_index].target_map.add_epsilon_target_state(state_index)

    # -- copy all origins of the original state machine
    # -- We need to cancel any acceptance, because the inverted engine now starts
    #    from a combination of the acceptance states and ends at the initial state.
    for state_index, state in SM.states.items():
        original_origin_list = [origin.clone() for origin in state.origins()]
        for origin in original_origin_list:
            origin.set_input_position_restore_f(False)
            origin.set_pre_context_id(E_PreContextIDs.NONE)
            origin.set_acceptance_f(False)
        result.states[state_index].origins().set(original_origin_list) # deepcopy implicit

    # -- only the ORIGINAL initial state becomes an acceptance state (end of inverse)
    result.states[SM.init_state_index].set_acceptance(True)

    # -- setup an epsilon transition from an new init state to all previous 
    #    acceptance states.
    new_init_state_index = result.create_new_init_state() 
    for state_index in original_acceptance_state_index_list:
        result.add_epsilon_transition(new_init_state_index, state_index)        

    # -- for uniqueness of state ids, clone the result
    return result.clone()    
Exemplo n.º 3
0
def do(SM_A, SM_B):
    """Complement Begin:

    Let SM_A match the set of lexemes LA and SM_B match the set of lexemes LB.
    Then, the complement begin operation 'NotBegin'

                           SM_C = NotBegin(SM_A, SM_B)

    results in a state machine SM_C, matches all lexemes of LA except for those
    that start with a lexeme from LB.

    EXAMPLE 1: 

          NotBegin([0-9]+, [0-9]) = \None

    EXAMPLE 2: 

          NotBegin(1(2?), 12) = 1

    Because the lexeme "12" is not to be matched by the result. The lexeme
    "1", though, does not start with "12". Thus, it remains.

    EXAMPLE 2: 

          NotBegin([a-z]+, print) = all identifiers except 'print'

    (C) 2013 Frank-Rene Schaefer
    """
    cutter = WalkAlong(SM_A, SM_B)
    if SM_B.get_init_state().is_acceptance():
        return special.get_none()

    cutter.do((SM_A.init_state_index, SM_B.init_state_index))

    # Delete orphaned and hopeless states in result
    cutter.result.clean_up()

    # Get propper state indices for result
    return beautifier.do(cutter.result)
Exemplo n.º 4
0
    test('x(1?2|A?B)x')
    test('x(1?2?|A?B?)x')

elif "Loops" in sys.argv:
    test('A+')
    test('A(B*)')
    test('A((BC)*)')
    test('((A+)B+)C+')
    test('(ABC|BC|C)+')

elif "BranchesLoops" in sys.argv:
    test('(AB|XY)+')
    test('(AB|XY)((DE|FG)*)')
    test('(((AB|XY)+)(DE|FG)+)(HI|JK)+')
    test('((AB|XY)(DE|FG)(HI|JK)|(DE|FG)(HI|JK)|(HI|JK))+')

elif "Misc" in sys.argv:
    test('((((((((p+)r)+i)+)n)+t)+e)+r)+')
    test('(printer|rinter|inter|nter|ter|er|r)+')
    test('(p?r?i?n?t?e?r|rinter|inter|nter|ter|er|r)+')
    test('(((((((((p+)r)+i)+)p)+r)+i)+n)+|(priprin|riprin|iprin|prin|rin|in|n)+)x?')

elif "Special" in sys.argv:
    test(get_none())
    test(get_all())
    sm = get_all()
    sm.get_init_state().set_acceptance(True)
    sm = beautifier.do(sm)
    test(sm)

Exemplo n.º 5
0
def snap_none(stream, PatternDict):
    return get_none()
Exemplo n.º 6
0
def cut_in(A, B):
    return module_cut_in.do(A, B)


def exec_print(ExprStr):
    exec("sme = %s" %
         ExprStr.replace("All", "All_sm").replace("None", "None_sm"))
    print "%s: -->" % ExprStr
    print beautifier.do(sme)


protocol = []
X = None
Y = None
All_sm = get_all()
None_sm = get_none()


def equal(X_str, Y_str):
    global X
    global Y
    global report
    exec("sm0 = " + X_str.replace("All", "All_sm").replace("None", "None_sm"))
    exec("sm1 = " + Y_str.replace("All", "All_sm").replace("None", "None_sm"))
    sm0 = beautifier.do(sm0)
    sm1 = beautifier.do(sm1)
    result = identity.do(sm0, sm1)
    if result is False:
        print "X:", X
        # print "Y:", Y
        print "Error"
Exemplo n.º 7
0
def do(SM_List):
    """Intersection: 

       Only match on patterns which are matched by all state machines
       in 'SM_List'.

       (C) 2013 Frank-Rene Schaefer
       ________________________________________________________________________

       A lexeme which matches all patterns must reach an acceptance in each 
       given state machine. That is, 
       
          For each state machine; there is a path from the init 
          state to an acceptance state triggered along the by 
          the characters of the lexeme.

       We cannot go forward, since we cannot omit a path upon non-fit.

       Now, consider the super-state consisting of all acceptance states
       of all state machines. There there must be a way backward from the 
       super-acceptance-state to the init state states. As soon, as a
       path is interupted, it can be thrown away. This can be achieved
       by reversed state machines which are combined into a single one.
       
       Reverse all state machines; The epsilon closure of the init state
       corresponds to the super acceptance state. The transitions in the
       super-state machine correspond to the way backwards in the state
       machine. For each feasible state in the super-state machine create
       a new state. 

       The acceptance state of the reversed state machines correspond to 
       the init state of the original state machines. If the super state
       contains an acceptance state of the original state, it can become
       an acceptance state of the intersection, because we now found a 
       path. The found state machine must be reversed at the end.

    """
    for sm in SM_List:
        if special.is_none(sm):         # If one state machine is '\None'
            return special.get_none()   # then, the intersection is '\None'

    reverse_sm_list          = [ reverse.do(sm)                            for sm in SM_List ]
    state_id_set_list        = [ set(sm.states.iterkeys())                 for sm in reverse_sm_list ]
    acceptance_state_id_list = [ set(sm.get_acceptance_state_index_list()) for sm in reverse_sm_list ]

    def has_one_from_each(StateIDSet_List, StateIDSet):
        """StateIDSet_List[i] is the set of state indices from state 
        machine 'i' in 'reverse_sm_list'. 

        RETURNS: True -- If the StateIDSet has at least one state 
                         from every state machine.
                 False -- If there is at least one state machine 
                          that has no state in 'StateIDSet'.
        """
        for state_id_set in StateIDSet_List:
            if state_id_set.isdisjoint(StateIDSet): 
                return False
        return True

    def get_merged_state(AcceptanceStateIndexList, EpsilonClosure):
        """Create the new target state in the state machine
           Accept only if all accept.
        """
        acceptance_f = has_one_from_each(AcceptanceStateIndexList, 
                                         EpsilonClosure)
        return State(AcceptanceF=acceptance_f)

    # Plain merge of all states of all state machines with an 
    # epsilon transition from the init state to all init states
    # of the reverse_sm
    sm = StateMachine()
    for rsm in reverse_sm_list:
        sm.states.update(rsm.states)
        sm.add_epsilon_transition(sm.init_state_index, rsm.init_state_index) 

    initial_state_epsilon_closure = sm.get_epsilon_closure(sm.init_state_index) 

    InitState = get_merged_state(acceptance_state_id_list, 
                                 initial_state_epsilon_closure)

    result    = StateMachine(InitStateIndex=index.get(), InitState=InitState)

    # (*) prepare the initial worklist
    worklist = [ ( result.init_state_index, initial_state_epsilon_closure) ]

    epsilon_closure_db = sm.get_epsilon_closure_db()

    while len(worklist) != 0:
        # 'start_state_index' is the index of an **existing** state in the state machine.
        # It was either created above, in StateMachine's constructor, or as a target
        # state index.
        start_state_index, start_state_combination = worklist.pop()
 
        # (*) compute the elementary trigger sets together with the 
        #     epsilon closure of target state combinations that they trigger to.
        #     In other words: find the ranges of characters where the state triggers to
        #     a unique state combination. E.g:
        #                Range        Target State Combination 
        #                [0:23]   --> [ State1, State2, State10 ]
        #                [24:60]  --> [ State1 ]
        #                [61:123] --> [ State2, State10 ]
        #
        elementary_trigger_set_infos = sm.get_elementary_trigger_sets(start_state_combination,
                                                                      epsilon_closure_db)
        ## DEBUG_print(start_state_combination, elementary_trigger_set_infos)

        # (*) loop over all elementary trigger sets
        for epsilon_closure_of_target_state_combination, trigger_set in elementary_trigger_set_infos.iteritems():
            #  -- if there is no trigger to the given target state combination, then drop it
            if trigger_set.is_empty(): 
                continue
            elif not has_one_from_each(state_id_set_list, epsilon_closure_of_target_state_combination):
                continue

            # -- add a new target state representing the state combination
            #    (if this did not happen yet)
            target_state_index = \
                 map_state_combination_to_index(epsilon_closure_of_target_state_combination)

            # -- if target state combination was not considered yet, then create 
            #    a new state in the state machine
            if not result.states.has_key(target_state_index):
                result.states[target_state_index] = get_merged_state(acceptance_state_id_list, 
                                                                     epsilon_closure_of_target_state_combination)

                worklist.append((target_state_index, epsilon_closure_of_target_state_combination))  

            # -- add the transition 'start state to target state'
            result.add_transition(start_state_index, trigger_set, target_state_index)

    if not result.has_acceptance_states():
        return StateMachine()
    else:
        return beautifier.do(reverse.do(result))
Exemplo n.º 8
0
def not_end(A, B):   return complement_end.do(A, B)
def not_in(A, B):    return complement_in.do(A, B)
def cut_begin(A, B): return module_cut_begin.do(A, B)
def cut_end(A, B):   return module_cut_end.do(A, B)
def cut_in(A, B):    return module_cut_in.do(A, B)

def exec_print(ExprStr):
    exec("sme = %s" % ExprStr.replace("All", "All_sm").replace("None", "None_sm"))
    print "%s: -->" % ExprStr
    print beautifier.do(sme)

protocol = []
X        = None
Y        = None
All_sm   = get_all()
None_sm  = get_none()

def equal(X_str, Y_str):
    global X
    global Y
    global report
    exec("sm0 = " + X_str.replace("All", "All_sm").replace("None", "None_sm"))
    exec("sm1 = " + Y_str.replace("All", "All_sm").replace("None", "None_sm"))
    sm0 = beautifier.do(sm0)
    sm1 = beautifier.do(sm1)
    result = identity.do(sm0, sm1)
    if result is False:
        print "X:", X
        # print "Y:", Y
        print "Error"
        print "%s: -->\n%s" % (X_str, sm0)