Пример #1
0
    def get_loop_terminal_code(self, TheLoopMapEntry, DoorIdLoop,
                               DoorIdLoopExit):
        """RETURNS: A loop terminal. 

        A terminal: (i)    Counts,
                    (ii)   checks possibly for the lexeme end, and
                    (iii)a either re-enters the loop, or
                    (iii)b transits to an appendix state machine (couple terminal).
        """
        IncidenceId = TheLoopMapEntry.incidence_id
        AppendixSmId = TheLoopMapEntry.appendix_sm_id
        TheCountAction = TheLoopMapEntry.count_action

        code = []
        if TheCountAction is not None:
            code.extend(
                TheCountAction.get_OpList(self.column_number_per_code_unit))

        if AppendixSmId is not None:
            if not lei.appendix_sm_has_transitions_f:
                # If there is no appendix, directly goto to the terminal.
                code.extend([Op.GotoDoorId(DoorID.incidence_id(AppendixSmId))])
            else:
                assert not self.lexeme_end_check_f
                # Couple Terminal: transit to appendix state machine.
                code.extend([
                    Op.Assign(E_R.ReferenceP, E_R.InputP),
                    Op.GotoDoorId(DoorID.state_machine_entry(AppendixSmId))
                ])
        elif not self.lexeme_end_check_f:
            # Loop Terminal: directly re-enter loop.
            code.append(Op.GotoDoorId(DoorIdLoop))
        else:
            # Check Terminal: check against lexeme end before re-entering loop.
            code.append(
                Op.GotoDoorIdIfInputPNotEqualPointer(DoorIdLoop,
                                                     E_R.LexemeEnd))
            if     self.column_number_per_code_unit is not None \
               and TheCountAction is not None \
               and TheCountAction.cc_type == E_CharacterCountType.COLUMN:
                # With reference counting, no column counting while looping.
                # => Do it now, before leaving.
                code.append(
                    Op.ColumnCountReferencePDeltaAdd(
                        E_R.InputP, self.column_number_per_code_unit, False))
            code.append(Op.GotoDoorId(DoorIdLoopExit))

        return Terminal(CodeTerminal(Lng.COMMAND_LIST(code)),
                        "<LOOP TERMINAL %i>" % IncidenceId, IncidenceId)
Пример #2
0
 def get_LexemeEndCheck_appendix(ccfactory, CC_Type):
     if not LexemeEndCheckF:
         return [Op.GotoDoorId(door_id_loop)]
     #
     #       .---------------.        ,----------.   no
     #   --->| Count Op |-------< LexemeEnd? >------> DoorIdOk
     #       '---------------'        '----+-----'
     #                                     | yes
     #                              .---------------.
     #                              |  Lexeme End   |
     #                              | Count Op |----> DoorIdOnLexemeEnd
     #                              '---------------'
     #
     elif ccfactory.requires_reference_p(
     ) and CC_Type == E_CharacterCountType.COLUMN:
         return [
             Op.GotoDoorIdIfInputPNotEqualPointer(door_id_loop,
                                                  E_R.LexemeEnd),
             Op.ColumnCountReferencePDeltaAdd(
                 E_R.InputP, ccfactory.column_count_per_chunk, False),
         ] + AfterBeyond
     else:
         return [
             Op.GotoDoorIdIfInputPNotEqualPointer(door_id_loop,
                                                  E_R.LexemeEnd),
         ] + AfterBeyond
Пример #3
0
def _add_newline(psml, SmNewlineOriginal):
    """Add a pair (newline state machine, terminal on newline) to 'psml'.

    When a newline occurs, the column count can be set to 1 and the line number
    is incremented. Then the indentation counting restarts.
    """
    assert SmNewlineOriginal is not None

    # Disconnect from machines being used elsewhere.
    SmNewline = SmNewlineOriginal.clone()
    SmNewline.set_id(dial_db.new_incidence_id())

    # The SmNewline has been used before in the main state machine with a
    # different incidence id. It is essential to clone!

    cl = [
        Op.LineCountAdd(1),
        Op.AssignConstant(E_R.Column, 1),
        Op.GotoDoorId(DoorID.incidence(E_IncidenceIDs.INDENTATION_HANDLER))
    ]
    terminal = Terminal(CodeTerminal(Lng.COMMAND_LIST(cl)),
                        "<INDENTATION NEWLINE>")
    terminal.set_incidence_id(SmNewline.get_id())

    psml.append((SmNewline, terminal))
Пример #4
0
def _add_suppressed_newline(psml, SmSuppressedNewlineOriginal):
    """Add a pair (suppressed newline, terminal on suppressed newline to 'psml'.

    A suppresed newline is not like a newline--the next line is considered as 
    being appended to the current line. Nevertheless the line number needs to
    incremented, just the column number is not reset to 1. Then, it continues
    with indentation counting.
    """
    if SmSuppressedNewlineOriginal is None:
        return

    # Disconnect from machines being used elsewhere.
    SmSuppressedNewline = SmSuppressedNewlineOriginal.clone()
    SmSuppressedNewline.set_id(dial_db.new_incidence_id())

    # The parser MUST ensure that if there is a newline suppressor, there MUST
    # be a newline being defined.

    cl = [
        Op.LineCountAdd(1),
        Op.AssignConstant(E_R.Column, 1),
        Op.GotoDoorId(DoorID.incidence(E_IncidenceIDs.INDENTATION_HANDLER)),
    ]
    terminal = Terminal(CodeTerminal(Lng.COMMAND_LIST(cl)),
                        "<INDENTATION SUPPRESSED NEWLINE>")
    terminal.set_incidence_id(SmSuppressedNewline.get_id())

    psml.append((SmSuppressedNewline, terminal))
Пример #5
0
    def _terminal_goto_to_looper(self,
                                 analyzer_list,
                                 IncidenceId,
                                 Name,
                                 required_register_set,
                                 Pattern=None):
        """Generate terminal that jumps to a 'looper'.
        """
        door_id = DoorID.state_machine_entry(analyzer_list[0].state_machine_id,
                                             self.terminal_factory.dial_db)
        goto_op = Op.GotoDoorId(door_id)
        goto_code = [Lng.COMMAND(goto_op, self.terminal_factory.dial_db)]

        if Pattern is None:
            return Terminal(CodeTerminal(goto_code),
                            Name,
                            IncidenceId,
                            RequiredRegisterSet=required_register_set,
                            dial_db=self.terminal_factory.dial_db)
        else:
            return self.terminal_factory.do_plain(
                CodeTerminal(goto_code),
                Pattern,
                Name,
                RequiredRegisterSet=required_register_set)
Пример #6
0
 def _cmd_list_Frame(self, TheCountAction, CmdList, DoorIdTarget):
     cmd_list = []
     if TheCountAction is not None:
         cmd_list.extend(
             TheCountAction.get_OpList(self.column_number_per_code_unit))
     cmd_list.extend(CmdList)
     cmd_list.append(Op.GotoDoorId(DoorIdTarget))
     return cmd_list
Пример #7
0
 def prepare(AppendixSm, OriginalIidDb):
     lcci = SmLineColumnCountInfo.from_DFA(CaMap, AppendixSm, False,
                                           Setup.buffer_encoding)
     cmd_list = self.get_count_code(lcci)
     target_door_id = DoorID.incidence(
         OriginalIidDb[AppendixSm.get_id()], self.dial_db)
     cmd_list.append(Op.GotoDoorId(target_door_id))
     return (AppendixSm.get_id(), cmd_list)
Пример #8
0
def _get_state_machine_vs_terminal_list(CloserPattern, OpenerPattern,
                                        DoorIdExit, dial_db):
    """Additionally to all characters, the loop shall walk along the 'closer'.
    If the closer matches, the range skipping exits. Characters need to be 
    counted properly.

    RETURNS: [0] list(state machine, terminal)
             [1] incidence id of auxiliary terminal that goto-s to the
                 loop entry.

    The auxiliary terminal is necessary since the DoorID of the loop entry
    cannot be known beforehand.
    """
    # DoorID of loop entry cannot be known beforehand.
    # => generate an intermediate door_id from where the loop is entered.
    iid_aux_reentry = dial.new_incidence_id()
    door_id_aux_reentry = dial.DoorID.incidence(iid_aux_reentry, dial_db)

    # Opener Pattern Reaction
    opener_op_list = [
        Op.Increment(E_R.Counter),
        Op.GotoDoorId(door_id_aux_reentry)
    ]

    # Closer Pattern Reaction
    closer_op_list = [
        Op.Decrement(E_R.Counter),
        Op.GotoDoorIdIfCounterEqualZero(DoorIdExit),
        Op.GotoDoorId(door_id_aux_reentry)
    ]

    def sm_terminal_pair(Pattern, Name, OpList, dial_db):
        sm = Pattern.get_cloned_sm(StateMachineId=dial.new_incidence_id())
        terminal = loop.MiniTerminal(Lng.COMMAND_LIST(OpList, dial_db), Name,
                                     sm.get_id())
        return sm, terminal

    smt_list = [
        sm_terminal_pair(OpenerPattern, "<SKIP NESTED RANGE OPENER>",
                         opener_op_list, dial_db),
        sm_terminal_pair(CloserPattern, "<SKIP NESTED RANGE CLOSER>",
                         closer_op_list, dial_db)
    ]

    return smt_list, iid_aux_reentry
Пример #9
0
 def create_DropOut(self, SM_State):
     if SM_State.is_acceptance():
         incidence_id = self.__incidence_id_of_bipd
         return OpList(
             Op.QuexDebug(
                 'pattern %i: backward input position detected\\n' %
                 incidence_id), Op.Increment(E_R.InputP),
             Op.GotoDoorId(DoorID.bipd_return(incidence_id)))
     else:
         return OpList(Op.QuexAssertNoPassage())
Пример #10
0
 def __replace_Lazy_DoorIdLoop(self, cmd, DoorIdLoop):
     if cmd.id == E_Op.GotoDoorId:
         if cmd.content.door_id != self.Lazy_DoorIdLoop: return cmd
         return Op.GotoDoorId(DoorIdLoop)
     elif cmd.id == E_Op.GotoDoorIdIfInputPNotEqualPointer:
         if cmd.content.door_id != self.Lazy_DoorIdLoop: return cmd
         return Op.GotoDoorIdIfInputPNotEqualPointer(
             DoorIdLoop, cmd.content.pointer)
     else:
         return cmd
Пример #11
0
    def _command(self, CC_Type, Parameter):
        if self.column_count_per_chunk is None:

            if CC_Type == E_CharacterCountType.BAD:
                return [Op.GotoDoorId(self.door_id_on_bad_indentation)]
            elif CC_Type == E_CharacterCountType.COLUMN:
                return [
                    Op.ColumnCountAdd(Parameter),
                ]
            elif CC_Type == E_CharacterCountType.GRID:
                return [
                    Op.ColumnCountGridAdd(Parameter),
                ]
            elif CC_Type == E_CharacterCountType.LINE:
                return [
                    Op.LineCountAdd(Parameter),
                    Op.AssignConstant(E_R.Column, 1),
                ]
        else:

            if CC_Type == E_CharacterCountType.BAD:
                return [
                    Op.ColumnCountReferencePDeltaAdd(
                        E_R.InputP, self.column_count_per_chunk, False),
                    Op.ColumnCountReferencePSet(E_R.InputP),
                    Op.GotoDoorId(self.door_id_on_bad_indentation)
                ]
            elif CC_Type == E_CharacterCountType.COLUMN:
                return []
            elif CC_Type == E_CharacterCountType.GRID:
                return [
                    Op.ColumnCountReferencePDeltaAdd(
                        E_R.InputP, self.column_count_per_chunk, True),
                    Op.ColumnCountGridAdd(Parameter),
                    Op.ColumnCountReferencePSet(E_R.InputP)
                ]
            elif CC_Type == E_CharacterCountType.LINE:
                return [
                    Op.LineCountAdd(Parameter),
                    Op.AssignConstant(E_R.Column, 1),
                    Op.ColumnCountReferencePSet(E_R.InputP)
                ]
Пример #12
0
def _get_indentation_handler_terminal(ModeName, dial_db):
    code = Lng.COMMAND_LIST([
        Op.IndentationHandlerCall(ModeName),
        Op.GotoDoorId(DoorID.continue_without_on_after_match(dial_db))
    ], dial_db)
    incidence_id = dial.new_incidence_id()
    terminal = Terminal(CodeTerminal(code),
                        "<CALL INDENTATION HANDLER>",
                        incidence_id,
                        dial_db=dial_db)

    return DoorID.incidence(incidence_id, dial_db), terminal
Пример #13
0
def get_skipper(TheAnalyzer, OpenerSequence, CloserSequence, OnSkipRangeOpen,
                DoorIdAfter, CounterDb):
    """
                                    .---<---+----------<------+------------------.
                                    |       |                 |                  |
                                    |       | not             | open_n += 1      |  
                                  .------.  | Closer[0]       |                  |
       -------------------------->| Loop +--'                 |                  |
                                  |      |                    | yes              | 
                                  |      |                    |                  |
                                  |      |          .-------------.              |
                                  |      +----->----| Opener[1-N] |              |
                                  |      |          |      ?      |              |
                                  |      |          '-------------'              |
                                  |      |                                       | open_n > 0
                                  |      |          .-------------.              | 
                                  |      +----->----| Closer[1-N] |--------------+------> RESTART
                                  |      |          |      ?      | open_n -= 1    else
                                  |      |          '-------------'             
                                  |      |                             
                                  |  BLC +-->-.  
                              .->-|      |     \                 Reload State 
            .-DoorID(S, 1)--./    '------'      \            .------------------.
         .--| after_reload  |                    \          .---------------.   |
         |  '---------------'                     '---------| before_reload |   |
         |                                                  '---------------'   |
         '---------------------------------------------------|                  |
                                                     success '------------------'     
                                                                     | failure      
                                                                     |            
                                                              .---------------.       
                                                              | SkipRangeOpen |       
                                                              '---------------'                                                                   

    """
    psml = _get_state_machine_vs_terminal_list(CloserSequence, OpenerSequence,
                                               CounterDb, DoorIdAfter)
    count_op_factory = CountInfoMap.from_LineColumnCount(
        CounterDb, NumberSet_All(), Lng.INPUT_P())
    result,          \
    door_id_beyond   = loop.do(count_op_factory,
                               OnLoopExit        = [ Op.GotoDoorId(DoorIdAfter) ],
                               LexemeEndCheckF   = False,
                               LexemeMaintainedF = False,
                               EngineType        = engine.FORWARD,
                               ReloadStateExtern = TheAnalyzer.reload_state,
                               ParallelSmTerminalPairList = psml)

    counter_variable = Lng.REGISTER_NAME(E_R.Counter)
    variable_db.require(counter_variable)
    result[0:0] = "%s = 0;\n" % counter_variable
    return result
Пример #14
0
    def _prepare_skip_character_set(self, MHI, Loopers, CaMap, ReloadState):
        """MHI = Mode hierarchie index."""
        if Loopers.skip is None: return [], [], []

        skipped_character_set, \
        pattern_str,           \
        aux_source_reference   = Loopers.combined_skip(CaMap)

        new_analyzer_list,        \
        new_terminal_list,    \
        loop_map,             \
        required_register_set = skip_character_set.do(self.terminal_factory.mode_name,
                                                      CaMap, skipped_character_set,
                                                      ReloadState,
                                                      self.terminal_factory.dial_db)

        self.required_register_set.update(required_register_set)

        extra_terminal_list = [
            self._terminal_goto_to_looper(new_analyzer_list,
                                          E_IncidenceIDs.SKIP, "<skip>",
                                          required_register_set)
        ]
        extra_terminal_list.extend(t for t in new_terminal_list)

        # Any skipped character must enter the skipper entry.
        goto_code = [
            Op.GotoDoorId(
                DoorID.incidence(E_IncidenceIDs.SKIP,
                                 self.terminal_factory.dial_db))
        ]
        new_ppt_list = []
        for lei in loop_map:
            new_incidence_id = dial.new_incidence_id()
            pattern = Pattern.from_character_set(lei.character_set,
                                                 new_incidence_id,
                                                 PatternString="<skip>",
                                                 Sr=aux_source_reference)
            # There is no reference pointer => Add directly
            count_code = lei.aux_count_action.get_OpList(None)
            code = Lng.COMMAND_LIST(count_code + goto_code,
                                    self.terminal_factory.dial_db)
            terminal = Terminal(CodeTerminal(code),
                                "ENTER SKIP:",
                                new_incidence_id,
                                dial_db=self.terminal_factory.dial_db)

            new_ppt_list.append(
                PPT(PatternPriority(MHI, new_incidence_id), pattern, terminal))

        return new_ppt_list, new_analyzer_list, extra_terminal_list
Пример #15
0
    def on_loop_after_appendix_drop_out(self, DoorIdLoop, ColumnNPerCodeUnit):
        # Upon drop-out, the input position is set to where the apendix
        # started. Then, the loop is re-entered.
        op_list = []

        if ColumnNPerCodeUnit is not None:
            op_list.append(
                Op.Assign(E_R.CountReferenceP,
                          E_R.LoopRestartP,
                          Condition="COLUMN"))

        op_list.extend([
            Op.Assign(E_R.InputP, E_R.LoopRestartP),
            Op.GotoDoorId(DoorIdLoop)
        ])

        return op_list
Пример #16
0
def get_skipper(TheAnalyzer, CloserSequence, CloserPattern, ModeName,
                OnSkipRangeOpen, DoorIdAfter, CounterDb):
    """
                                        .---<---+----------<------+
                                        |       |                 |        
                                        |       | not             |       
                                      .------.  | Closer[0]       |       
       ------------------------------>| Loop +--'                 |       
                                      |      |                    | no    
                                      |      |                    |       
                                      |      |          .-------------.          
                                      |      +----->----| Closer[1-N] |------------> RESTART
                                      |      |          |      ?      |   yes           
                                      |      |          '-------------'             
                                      |      |                             
                                      |  BLC +-->-.  
                                  .->-|      |     \                 Reload State 
                .-DoorID(S, 1)--./    '------'      \             .-----------------.
           .----| after_reload  |                    \          .---------------.   |
           |    '---------------'                     '---------| before_reload |   |
           |                                                    '---------------'   |
           '-----------------------------------------------------|                  |
                                                         success '------------------'     
                                                                         | failure      
                                                                         |            
                                                                  .---------------.       
                                                                  | SkipRangeOpen |       
                                                                  '---------------'                                                                   

    """
    psml = _get_state_machine_vs_terminal_list(CloserSequence, CounterDb)
    count_op_factory = CountInfoMap.from_LineColumnCount(
        CounterDb, NumberSet_All(), Lng.INPUT_P())
    result,          \
    door_id_beyond   = loop.do(count_op_factory,
                               OnLoopExit        = [ Op.GotoDoorId(DoorID.continue_without_on_after_match()) ],
                               LexemeEndCheckF   = False,
                               LexemeMaintainedF = False,
                               EngineType        = engine.FORWARD,
                               ReloadStateExtern = TheAnalyzer.reload_state,
                               ParallelSmTerminalPairList = psml)
    return result
Пример #17
0
    def __init__(self, ColumnNPerCodeUnit, UserBeforeEntryOpList,
                 UserOnLoopExitDoorId):
        # Counting Actions upon: loop entry/exit; before/after reload
        #
        on_loop_entry_count,    \
        on_loop_exit_count,     \
        on_before_reload_count, \
        on_after_reload_count   = self.__prepare_count_actions(ColumnNPerCodeUnit)

        # Input pointer positioning: loop entry/exit; before/after reload
        #
        on_loop_entry,            \
        on_loop_reentry_pos,      \
        on_loop_exit_pos          = self.__prepare_positioning_at_loop_begin_and_exit(ColumnNPerCodeUnit)

        on_before_reload_pos,     \
        on_after_reload_pos       = self.__prepare_positioning_before_and_after_reload()
        on_before_reload_pos_apx, \
        on_after_reload_pos_apx   = self.__prepare_positioning_before_and_after_reload(AppendixSmF=True)

        # _____________________________________________________________________
        #
        if UserBeforeEntryOpList is None: UserBeforeEntryOpList = []
        self.on_loop_entry = OpList.concatinate(on_loop_entry,
                                                on_loop_reentry_pos,
                                                on_loop_entry_count,
                                                UserBeforeEntryOpList)
        self.on_loop_reentry = OpList.from_iterable(on_loop_reentry_pos)
        self.on_loop_exit = OpList.concatinate(
            on_loop_exit_pos, on_loop_exit_count,
            [Op.GotoDoorId(UserOnLoopExitDoorId)])

        self.on_before_reload = OpList.concatinate(on_before_reload_pos,
                                                   on_before_reload_count)
        self.on_before_reload_in_appendix = OpList.from_iterable(
            on_before_reload_pos_apx)

        self.on_after_reload = OpList.concatinate(on_after_reload_pos,
                                                  on_after_reload_count)
        self.on_after_reload_in_appendix = OpList.from_iterable(
            on_after_reload_pos_apx)
Пример #18
0
    def get_couple_terminal_cmd_list(self, CA, CombinedAppendixSm,
                                     OriginalIidDb):
        """CA:                 Count action for the character set of the loop 
                               entry.
           CombinedAppendixSm: (combined) appendix sm where to jump upon 
                               triggering of the character set.
           OriginalIidDb:      Appendix sm id --> original iid of the state machine
                                                  where it came from.

        RETURNS: [0] CmdList -- for loop count action and transition to appendix
                                state machine or entry into according terminal.
                 [1] True, if there is a transition to an appendix state machine
                     False, if not
                 
        """
        transition_to_appendix_f = CombinedAppendixSm.get_init_state(
        ).has_transitions()
        acceptance_id_set = CombinedAppendixSm.acceptance_id_set()
        combined_appendix_sm_id = CombinedAppendixSm.get_id()

        cmd_list = []
        if CA is not None:
            cmd_list.extend(CA.get_OpList(self.column_number_per_code_unit))

        if not transition_to_appendix_f:
            # NO appendix after first transition => jump to appendix terminal.
            assert len(acceptance_id_set) == 1
            iid_original = OriginalIidDb[acceptance_id_set.pop()]
            target_door_id = DoorID.incidence(iid_original, self.dial_db)
            transition_to_appendix_f = False
        else:
            # appendix after first transition. => jump to appendix state machine.
            self.__appendix_dfa_present_f = True
            cmd_list.extend([
                Op.Assign(E_R.LoopRestartP, E_R.InputP),
                Op.Assign(E_R.LexemeStartP, E_R.InputP)
            ])
            target_door_id = DoorID.state_machine_entry(
                combined_appendix_sm_id, self.dial_db)
        cmd_list.append(Op.GotoDoorId(target_door_id))
        return cmd_list, transition_to_appendix_f
Пример #19
0
 def create_DropOut(self, SM_State):
     return OpList(Op.GotoDoorId(DoorID.global_end_of_pre_context_check()))
Пример #20
0
    "space": E_CharacterCountType.COLUMN,
    "grid": E_CharacterCountType.GRID,
    "newline": E_CharacterCountType.LINE,
    "begin(newline suppressor)": E_CharacterCountType.BEGIN_NEWLINE_SUPPRESSOR,
    "begin(newline)": E_CharacterCountType.BEGIN_NEWLINE,
    "begin(comment to newline)": E_CharacterCountType.BEGIN_COMMENT_TO_NEWLINE,
    "end(newline)": E_CharacterCountType.END_NEWLINE,
    "bad": E_CharacterCountType.BAD,
    "whitespace": E_CharacterCountType.WHITESPACE,
}

cc_type_name_db = dict((value, key) for key, value in cc_type_db.iteritems())

count_operation_db_without_reference = {
    E_CharacterCountType.BAD:
    lambda Parameter, Dummy=None: [Op.GotoDoorId(Parameter)],
    E_CharacterCountType.COLUMN:
    lambda Parameter, Dummy=None: [Op.ColumnCountAdd(Parameter)],
    E_CharacterCountType.GRID:
    lambda Parameter, Dummy=None: [Op.ColumnCountGridAdd(Parameter)],
    E_CharacterCountType.LINE:
    lambda Parameter, Dummy=None: [
        Op.LineCountAdd(Parameter),
        Op.AssignConstant(E_R.Column, 1),
    ],
    E_CharacterCountType.LOOP_ENTRY:
    lambda Parameter, Dummy=None: [],
    E_CharacterCountType.LOOP_EXIT:
    lambda Parameter, Dummy=None: [],
    E_CharacterCountType.BEFORE_RELOAD:
    lambda Parameter, Dummy=None: [],
Пример #21
0
    "grid":                      E_CharacterCountType.GRID,
    "newline":                   E_CharacterCountType.LINE,
    "bad":                       E_CharacterCountType.BAD,
    "whitespace":                E_CharacterCountType.WHITESPACE,
    # Following are only webbed into the 'CA_Map' to detect overlaps:
    "begin(newline suppressor)": E_CharacterCountType.X_BEGIN_NEWLINE_SUPPRESSOR,
    "begin(newline)":            E_CharacterCountType.X_BEGIN_NEWLINE,
    "begin(comment to newline)": E_CharacterCountType.X_BEGIN_COMMENT_TO_NEWLINE,
    "end(newline)":              E_CharacterCountType.X_END_NEWLINE,
}

cc_type_name_db = dict((value, key) for key, value in cc_type_db.iteritems())

count_operation_db_without_reference = {
    E_CharacterCountType.BAD:    lambda Parameter, Dummy=None, Dummy2=None: [ 
        Op.GotoDoorId(Parameter)
    ],
    E_CharacterCountType.COLUMN: lambda Parameter, Dummy=None, Dummy2=None: [
        Op.ColumnCountAdd(Parameter)
    ],
    E_CharacterCountType.GRID:   lambda Parameter, Dummy=None, Dummy2=None: [
        Op.ColumnCountGridAdd(Parameter)
    ],
    E_CharacterCountType.LINE:   lambda Parameter, Dummy=None, Dummy2=None: [
        Op.LineCountAdd(Parameter),
        Op.AssignConstant(E_R.Column, 1),
    ],
    E_CharacterCountType.LOOP_ENTRY: lambda Parameter, Dummy=None, Dummy2=None: [ 
    ],
    E_CharacterCountType.LOOP_EXIT: lambda Parameter, Dummy=None, Dummy2=None: [ 
    ],
Пример #22
0
def do(Data, TheAnalyzer):
    """________________________________________________________________________
    Counting whitespace at the beginning of a line.

                   .-----<----+----------<--------------+--<----.
                   |          | count                   |       | count = 0
                   |          | whitespace              |       |
                 .---------.  |                         |       |
       --------->|         +--'                         |       |
                 |         |                            |       |
                 |         |                            |       |
                 |         |          .------------.    |       |
                 |         +----->----| suppressor |----'       |
                 |         |          | + newline  |            | 
                 | COUNTER |          '------------'            |
                 |         |          .---------.               |
                 |         +----->----| newline |---------------'
                 |         |          '---------'
                 |         |          .----------------.
                 |         |----->----| on_indentation |---------> RESTART
                 '---------'   else   '----------------'
                                           

    Generate an indentation counter. An indentation counter is entered upon 
    the detection of a newline (which is not followed by a newline suppressor).
    
    Indentation Counter:

                indentation = 0
                column      = 0
                       |
                       |<------------------------.
                .-------------.                  |
                | INDENTATION |       indentation += count
                | COUNTER     |       column      += count
                '-------------'                  |
                       |                         |
                       +-------- whitspace -->---'
                       |
                   Re-Enter 
                   Analyzer
                                            
    An indentation counter is a single state that iterates to itself as long
    as whitespace occurs. During that iteration the column counter is adapted.
    There are two types of adaption:

       -- 'normal' adaption by a fixed delta. This adaption happens upon
          normal space characters.

       -- 'grid' adaption. When a grid character occurs, the column number
          snaps to a value given by a grid size parameter.

    When a newline occurs the indentation counter exits and restarts the
    lexical analysis. If the newline is not followed by a newline suppressor
    the analyzer will immediately be back to the indentation counter state.
    ___________________________________________________________________________
    """
    counter_db = Data["counter_db"]
    isetup = Data["indentation_setup"]
    incidence_db = Data["incidence_db"]
    default_ih_f = Data["default_indentation_handler_f"]
    mode_name = Data["mode_name"]
    sm_suppressed_newline = Data["sm_suppressed_newline"]
    sm_newline = isetup.sm_newline.get()
    sm_comment = isetup.sm_comment.get()

    assert sm_suppressed_newline is None or sm_suppressed_newline.is_DFA_compliant(
    )
    assert sm_newline is None or sm_newline.is_DFA_compliant()
    assert sm_comment is None or sm_comment.is_DFA_compliant()

    # -- 'on_indentation' == 'on_beyond':
    #     A handler is called as soon as an indentation has been detected.
    after_beyond = [
        Op.IndentationHandlerCall(default_ih_f, mode_name),
        Op.GotoDoorId(DoorID.continue_without_on_after_match())
    ]

    # -- 'on_bad_indentation' is invoked if a character appeared that has been
    #    explicitly disallowed to be used as indentation.
    bad_indentation_iid = dial_db.new_incidence_id()

    if Setup.buffer_based_analyzis_f: reload_state = None
    else: reload_state = TheAnalyzer.reload_state

    sm_terminal_list = _get_state_machine_vs_terminal_list(
        sm_suppressed_newline, isetup.sm_newline.get(),
        isetup.sm_comment.get(), counter_db)

    # 'whitespace' --> normal counting
    # 'bad'        --> goto bad character indentation handler
    # else         --> non-whitespace detected => handle indentation
    ccfactory = CountOpFactory.from_ParserDataIndentation(
        isetup, counter_db, Lng.INPUT_P(),
        DoorID.incidence(bad_indentation_iid))

    # (*) Generate Code
    code,          \
    door_id_beyond = loop.do(ccfactory,
                             AfterBeyond       = after_beyond,
                             EngineType        = TheAnalyzer.engine_type,
                             ReloadStateExtern = reload_state,
                             LexemeMaintainedF = True,
                             ParallelSmTerminalPairList = sm_terminal_list)

    _code_terminal_on_bad_indentation_character(code, isetup, mode_name,
                                                incidence_db,
                                                bad_indentation_iid)

    return code
Пример #23
0
def do(ModeName, CaMap, OpenerPattern, CloserPattern, DoorIdExit, ReloadState,
       dial_db):
    """
                                    .---<---+----------<------+------------------.
                                    |       |                 |                  |
                                    |       | not             | open_n += 1      |  
                                  .------.  | Closer[0]       |                  |
       -------------------------->| Loop +--'                 |                  |
                                  |      |                    | yes              | 
                                  |      |                    |                  |
                                  |      |          .-------------.              |
                                  |      +----->----| Opener[1-N] |              |
                                  |      |          |      ?      |              |
                                  |      |          '-------------'              |
                                  |      |                                       | open_n > 0
                                  |      |          .-------------.              | 
                                  |      +----->----| Closer[1-N] |--------------+------> RESTART
                                  |      |          |      ?      | open_n -= 1    else
                                  |      |          '-------------'             
                                  |      |                             
                                  |  BLC +-->-.  
                              .->-|      |     \                 Reload State 
            .-DoorID(S, 1)--./    '------'      \            .------------------.
         .--| after_reload  |                    \          .---------------.   |
         |  '---------------'                     '---------| before_reload |   |
         |                                                  '---------------'   |
         '---------------------------------------------------|                  |
                                                     success '------------------'     
                                                                     | failure      
                                                                     |            
                                                              .---------------.       
                                                              | SkipRangeOpen |       
                                                              '---------------'                                                                   

    """
    psml, \
    iid_aux_reentry = _get_state_machine_vs_terminal_list(CloserPattern, OpenerPattern,
                                                          DoorIdExit, dial_db)

    if ReloadState: engine_type = ReloadState.engine_type
    else: engine_type = None

    # The first opening pattern must have matched --> counter = 1
    entry_op_list = OpList(Op.AssignConstant(E_R.Counter, 1))

    analyzer_list,         \
    terminal_list,         \
    loop_map,              \
    door_id_loop,          \
    required_register_set, \
    run_time_counter_f     = loop.do(CaMap,
                                     BeforeEntryOpList          = entry_op_list,
                                     OnLoopExitDoorId           = DoorIdExit,
                                     EngineType                 = engine_type,
                                     ReloadStateExtern          = ReloadState,
                                     ParallelSmTerminalPairList = psml,
                                     dial_db                    = dial_db,
                                     ModeName                   = ModeName)

    reentry_op_list = [Op.GotoDoorId(door_id_loop)]
    terminal_list.append(
        Terminal(CodeTerminal(Lng.COMMAND_LIST(reentry_op_list, dial_db)),
                 Name="<SKIP NESTED RANGE REENTRY>",
                 IncidenceId=iid_aux_reentry,
                 dial_db=dial_db))

    required_register_set.add(E_R.Counter)
    return analyzer_list, \
           terminal_list, \
           required_register_set, \
           run_time_counter_f
Пример #24
0
 def on_loop_after_appendix_drop_out(self, DoorIdLoop):
     # 'CharacterBeginP' has been assigned in the 'Couple Terminal'.
     # (see ".get_loop_terminal_code()").
     return Lng.COMMAND_LIST(
         [Op.Assign(E_R.InputP, E_R.ReferenceP),
          Op.GotoDoorId(DoorIdLoop)])
Пример #25
0
def do(Data, TheAnalyzer):
    """Fast implementation of character set skipping machine.
    ________________________________________________________________________
    As long as characters of a given character set appears it iterates: 

                                 input in Set
                                   .--<---.
                                  |       |
                              .-------.   |
                   --------->( SKIPPER )--+----->------> RESTART
                              '-------'       input 
                                            not in Set

    ___________________________________________________________________________
    NOTE: The 'TerminalSkipRange' takes care that it transits immediately to 
    the indentation handler, if it ends on 'newline'. This is not necessary
    for 'TerminalSkipCharacterSet'. Quex refuses to work on 'skip sets' when 
    they match common lexemes with the indentation handler.
    ___________________________________________________________________________

    Precisely, i.e. including counter and reload actions:

    START
      |
      |    .----------------------------------------------.
      |    |.-------------------------------------------. |
      |    ||.----------------------------------------. | |
      |    |||                                        | | |
      |    |||  .-DoorID(S, a)--.    transition       | | |
      |    || '-|  gridstep(cn) |       map           | | |        
      |    ||   '---------------'\    .------.        | | |        
      |    ||   .-DoorID(S, b)--. '->-|      |        | | |       
      |    |'---|  ln += 1      |--->-| '\t' +-->-----' | |      
      |    |    '---------------'     |      |          | |     
      |    |    .-DoorID(S, c)--.     | ' '  +-->-------' |   
      |    '----|  cn += 1      |--->-|      |            |   
      |         '---------------'     | '\n' +-->---------'              
      |                               |      |                  .-DropOut ------.        
      |         .-DoorID(S, 0)--.     | else +-->---------------| on_exit       |                                
      '------>--| on_entry      |--->-|      |                  '---------------'        
                '---------------'     |  BLC +-->-.  
                                  .->-|      |     \                 Reload State 
                .-DoorID(S, 1)--./    '------'      \             .-----------------.
           .----| after_reload  |                    \          .---------------.   |
           |    '---------------'                     '---------| before_reload |   |
           |                                                    '---------------'   |
           '-----------------------------------------------------|                  |
                                                         success '------------------'     
                                                                         | failure      
                                                                         |            
                                                                  .---------------.       
                                                                  | End of Stream |       
                                                                  '---------------'                                                                   

    NOTE: If dynamic character size codings, such as UTF8, are used as engine codecs,
          then the single state may actually be split into a real state machine of
          states.
    """
    counter_db = Data["counter_db"]
    character_set = Data["character_set"]

    if Setup.buffer_based_analyzis_f:
        reload_state = None
    else:
        reload_state = TheAnalyzer.reload_state

    result,        \
    door_id_beyond = loop.do(CountOpFactory.from_ParserDataLineColumn(counter_db, character_set, Lng.INPUT_P()),
                             AfterBeyond       = [ Op.GotoDoorId(DoorID.continue_without_on_after_match()) ],
                             LexemeEndCheckF   = False,
                             LexemeMaintainedF = False,
                             EngineType        = engine.FORWARD,
                             ReloadStateExtern = reload_state)

    assert isinstance(result, list)
    return result