Example #1
0
    def __init__(self,
                 CoreSM,
                 PreContextSM=None,
                 PostContextSM=None,
                 BeginOfLineF=False,
                 EndOfLineF=False,
                 AllowStateMachineTrafoF=None,
                 fh=-1):
        assert AllowStateMachineTrafoF is not None
        pre_context = PreContextSM
        core_sm = CoreSM
        post_context = PostContextSM

        # (1) Character/Newline counting
        #
        #     !! BEFORE Transformation !!
        #
        #     Currently 'transition number' is equal to 'character number'. After
        #     transformation a transition may represent a byte or whatever the codec
        #     does to the state machine.
        self.__newline_n, self.__character_n = character_counter.do(CoreSM)

        # (2) [Optional] Transformation according to Codec Information
        #
        #     !! BEFORE Pre- and Post-Context Setup !!
        #
        #     Because pre-context state machines and pseudo-ambiguous state machines
        #     are inverted. They need to be inverted according to the transformed codec.
        #     !! AVOID Double Transformation !!
        #     The transformation should actually only be allowed during the pattern-action
        #     definition inside a mode --> flag 'AllowStateMachineTrafoF'
        if     AllowStateMachineTrafoF \
           and Setup.buffer_codec_transformation_info is not None:
            sm = transformation.try_this(pre_context, fh)
            if sm is not None: pre_context = sm
            sm = transformation.try_this(core_sm, fh)
            if sm is not None: core_sm = sm
            sm = transformation.try_this(post_context, fh)
            if sm is not None: post_context = sm

        self.__sm = core_sm

        # (3) Pre- and Post-Context Setup
        self.__post_context_f = (post_context is not None)

        self.__sm,                               \
        self.__input_position_search_backward_sm = setup_post_context.do(self.__sm, post_context, EndOfLineF, fh=fh)

        self.__pre_context_sm_inverse = setup_pre_context.do(
            self.__sm, pre_context, BeginOfLineF)

        self.__pre_context_trivial_begin_of_line_f = (
            BeginOfLineF and self.__pre_context_sm_inverse is None)

        self.__validate(fh)
Example #2
0
    def __init__(self, CoreSM, PreContextSM=None, PostContextSM=None, 
                 BeginOfLineF=False, EndOfLineF=False, 
                 AllowStateMachineTrafoF=None, fh=-1):
        assert AllowStateMachineTrafoF is not None
        pre_context  = PreContextSM
        core_sm      = CoreSM
        post_context = PostContextSM

        # (1) Character/Newline counting
        #
        #     !! BEFORE Transformation !!
        #
        #     Currently 'transition number' is equal to 'character number'. After 
        #     transformation a transition may represent a byte or whatever the codec 
        #     does to the state machine.
        self.__newline_n, self.__character_n = character_counter.do(CoreSM)

        # (2) [Optional] Transformation according to Codec Information
        #
        #     !! BEFORE Pre- and Post-Context Setup !!
        #
        #     Because pre-context state machines and pseudo-ambiguous state machines
        #     are inverted. They need to be inverted according to the transformed codec.
        #     !! AVOID Double Transformation !!
        #     The transformation should actually only be allowed during the pattern-action
        #     definition inside a mode --> flag 'AllowStateMachineTrafoF' 
        if     AllowStateMachineTrafoF \
           and Setup.buffer_codec_transformation_info is not None:
            sm = transformation.try_this(pre_context, fh)
            if sm is not None: pre_context = sm
            sm = transformation.try_this(core_sm, fh)
            if sm is not None: core_sm = sm
            sm = transformation.try_this(post_context, fh)
            if sm is not None: post_context = sm

        self.__sm = core_sm

        # (3) Pre- and Post-Context Setup
        self.__post_context_f = (post_context is not None)

        self.__sm,                               \
        self.__input_position_search_backward_sm = setup_post_context.do(self.__sm, post_context, EndOfLineF, fh=fh) 

        self.__pre_context_sm_inverse = setup_pre_context.do(self.__sm, pre_context, BeginOfLineF)

        self.__pre_context_trivial_begin_of_line_f = (BeginOfLineF and self.__pre_context_sm_inverse is None)
        
        self.__validate(fh)
Example #3
0
def do(A, B):
    """RETURNS: True  - if A == SUPERSET of B
                False - if not
    """
    if isinstance(A, StateMachine):
        assert isinstance(B, StateMachine)
        return Checker(A, B).do()

    assert not isinstance(B, StateMachine)
    # (*) Core Pattern ________________________________________________________
    #
    #     (including the mounted post context, if there is one).
    #
    # NOTE: Post-conditions do not change anything, since they match only when
    #       the whole lexeme has matched (from begin to end of post condition).
    #       Post-conditions only tell something about the place where the 
    #       analyzer returns after the match.
    superset_f = Checker(A.sm, B.sm).do()

    if not superset_f: return False

    # NOW: For the core state machines it holds: 
    #
    #                      'core(A)' matches a super set of 'core(B)'.
    #

    # (*) Pre-Condition _______________________________________________________
    #
    if not A.has_pre_context(): 
        # core(A) is a superset of core(B). 
        # A is not restricted. B may be (who cares).
        # => A can match more than B.
        return True

    # NOW: Acceptance of A is restricted by a pre-context.
    #
    if not B.has_pre_context(): 
        # A is restricted by pre-context, B is not.
        # => B can match things that A cannot. 
        return False

    # NOW: A is restricted by pre-context. 
    #      B is restricted by pre-context. 
    #
    #      For A to be a superset of B, A must be less or equally restricted than B.
    #
    #                 pre(B) is a superset of pre(A) 
    # 
    #
    if B.pre_context_trivial_begin_of_line_f:
        if not A.pre_context_trivial_begin_of_line_f:
            # pre(A) can never be a subset of pre(B)
            return False
        else:
            # pre(A) = pre(B) which fulfills the condition
            return True

    # NOW: B is a 'real' pre-context not only a 'begin-of-line'
    #
    # Decision about "pre(A) is subset of pre(B)" done by Checker
    if not A.pre_context_trivial_begin_of_line_f:
        A_pre_sm = A.inverse_pre_context_sm
    else:
        # A contains only 'begin-of-line'. Note, however, that 
        # -- newline definition may include '\r\n' so inversion is 
        #    required. 
        # -- at this point in time we are dealing with transformed 
        #    machines. So this has also to be transformed.
        A_pre_sm = StateMachine.from_sequence("\n").get_inverse()
        A_pre_sm = transformation.try_this(A_pre_sm, fh=-1)

    return Checker(B.inverse_pre_context_sm, A_pre_sm).do()
Example #4
0
def do(A, B):
    """RETURNS: True  - if A == SUPERSET of B
                False - if not
    """
    if isinstance(A, StateMachine):
        assert isinstance(B, StateMachine)
        return Checker(A, B).do()

    assert not isinstance(B, StateMachine)
    # (*) Core Pattern ________________________________________________________
    #
    #     (including the mounted post context, if there is one).
    #
    # NOTE: Post-conditions do not change anything, since they match only when
    #       the whole lexeme has matched (from begin to end of post condition).
    #       Post-conditions only tell something about the place where the
    #       analyzer returns after the match.
    superset_f = Checker(A.sm, B.sm).do()

    if not superset_f: return False

    # NOW: For the core state machines it holds:
    #
    #                      'core(A)' matches a super set of 'core(B)'.
    #

    # (*) Pre-Condition _______________________________________________________
    #
    if not A.has_pre_context():
        # core(A) is a superset of core(B).
        # A is not restricted. B may be (who cares).
        # => A can match more than B.
        return True

    # NOW: Acceptance of A is restricted by a pre-context.
    #
    if not B.has_pre_context():
        # A is restricted by pre-context, B is not.
        # => B can match things that A cannot.
        return False

    # NOW: A is restricted by pre-context.
    #      B is restricted by pre-context.
    #
    #      For A to be a superset of B, A must be less or equally restricted than B.
    #
    #                 pre(B) is a superset of pre(A)
    #
    #
    if B.pre_context_trivial_begin_of_line_f:
        if not A.pre_context_trivial_begin_of_line_f:
            # pre(A) can never be a subset of pre(B)
            return False
        else:
            # pre(A) = pre(B) which fulfills the condition
            return True

    # NOW: B is a 'real' pre-context not only a 'begin-of-line'
    #
    # Decision about "pre(A) is subset of pre(B)" done by Checker
    if not A.pre_context_trivial_begin_of_line_f:
        A_pre_sm = A.inverse_pre_context_sm
    else:
        # A contains only 'begin-of-line'. Note, however, that
        # -- newline definition may include '\r\n' so inversion is
        #    required.
        # -- at this point in time we are dealing with transformed
        #    machines. So this has also to be transformed.
        A_pre_sm = StateMachine.from_sequence("\n").get_inverse()
        A_pre_sm = transformation.try_this(A_pre_sm, fh=-1)

    return Checker(B.inverse_pre_context_sm, A_pre_sm).do()