Spaces:
Paused
Paused
| # | |
| # Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. | |
| # Use of this file is governed by the BSD 3-clause license that | |
| # can be found in the LICENSE.txt file in the project root. | |
| # | |
| from enum import IntEnum | |
| # need forward declaration | |
| Lexer = None | |
| class LexerActionType(IntEnum): | |
| CHANNEL = 0 #The type of a {@link LexerChannelAction} action. | |
| CUSTOM = 1 #The type of a {@link LexerCustomAction} action. | |
| MODE = 2 #The type of a {@link LexerModeAction} action. | |
| MORE = 3 #The type of a {@link LexerMoreAction} action. | |
| POP_MODE = 4 #The type of a {@link LexerPopModeAction} action. | |
| PUSH_MODE = 5 #The type of a {@link LexerPushModeAction} action. | |
| SKIP = 6 #The type of a {@link LexerSkipAction} action. | |
| TYPE = 7 #The type of a {@link LexerTypeAction} action. | |
| class LexerAction(object): | |
| __slots__ = ('actionType', 'isPositionDependent') | |
| def __init__(self, action:LexerActionType): | |
| self.actionType = action | |
| self.isPositionDependent = False | |
| def __hash__(self): | |
| return hash(self.actionType) | |
| def __eq__(self, other): | |
| return self is other | |
| # | |
| # Implements the {@code skip} lexer action by calling {@link Lexer#skip}. | |
| # | |
| # <p>The {@code skip} command does not have any parameters, so this action is | |
| # implemented as a singleton instance exposed by {@link #INSTANCE}.</p> | |
| class LexerSkipAction(LexerAction): | |
| # Provides a singleton instance of this parameterless lexer action. | |
| INSTANCE = None | |
| def __init__(self): | |
| super().__init__(LexerActionType.SKIP) | |
| def execute(self, lexer:Lexer): | |
| lexer.skip() | |
| def __str__(self): | |
| return "skip" | |
| LexerSkipAction.INSTANCE = LexerSkipAction() | |
| # Implements the {@code type} lexer action by calling {@link Lexer#setType} | |
| # with the assigned type. | |
| class LexerTypeAction(LexerAction): | |
| __slots__ = 'type' | |
| def __init__(self, type:int): | |
| super().__init__(LexerActionType.TYPE) | |
| self.type = type | |
| def execute(self, lexer:Lexer): | |
| lexer.type = self.type | |
| def __hash__(self): | |
| return hash((self.actionType, self.type)) | |
| def __eq__(self, other): | |
| if self is other: | |
| return True | |
| elif not isinstance(other, LexerTypeAction): | |
| return False | |
| else: | |
| return self.type == other.type | |
| def __str__(self): | |
| return "type(" + str(self.type) + ")" | |
| # Implements the {@code pushMode} lexer action by calling | |
| # {@link Lexer#pushMode} with the assigned mode. | |
| class LexerPushModeAction(LexerAction): | |
| __slots__ = 'mode' | |
| def __init__(self, mode:int): | |
| super().__init__(LexerActionType.PUSH_MODE) | |
| self.mode = mode | |
| # <p>This action is implemented by calling {@link Lexer#pushMode} with the | |
| # value provided by {@link #getMode}.</p> | |
| def execute(self, lexer:Lexer): | |
| lexer.pushMode(self.mode) | |
| def __hash__(self): | |
| return hash((self.actionType, self.mode)) | |
| def __eq__(self, other): | |
| if self is other: | |
| return True | |
| elif not isinstance(other, LexerPushModeAction): | |
| return False | |
| else: | |
| return self.mode == other.mode | |
| def __str__(self): | |
| return "pushMode(" + str(self.mode) + ")" | |
| # Implements the {@code popMode} lexer action by calling {@link Lexer#popMode}. | |
| # | |
| # <p>The {@code popMode} command does not have any parameters, so this action is | |
| # implemented as a singleton instance exposed by {@link #INSTANCE}.</p> | |
| class LexerPopModeAction(LexerAction): | |
| INSTANCE = None | |
| def __init__(self): | |
| super().__init__(LexerActionType.POP_MODE) | |
| # <p>This action is implemented by calling {@link Lexer#popMode}.</p> | |
| def execute(self, lexer:Lexer): | |
| lexer.popMode() | |
| def __str__(self): | |
| return "popMode" | |
| LexerPopModeAction.INSTANCE = LexerPopModeAction() | |
| # Implements the {@code more} lexer action by calling {@link Lexer#more}. | |
| # | |
| # <p>The {@code more} command does not have any parameters, so this action is | |
| # implemented as a singleton instance exposed by {@link #INSTANCE}.</p> | |
| class LexerMoreAction(LexerAction): | |
| INSTANCE = None | |
| def __init__(self): | |
| super().__init__(LexerActionType.MORE) | |
| # <p>This action is implemented by calling {@link Lexer#popMode}.</p> | |
| def execute(self, lexer:Lexer): | |
| lexer.more() | |
| def __str__(self): | |
| return "more" | |
| LexerMoreAction.INSTANCE = LexerMoreAction() | |
| # Implements the {@code mode} lexer action by calling {@link Lexer#mode} with | |
| # the assigned mode. | |
| class LexerModeAction(LexerAction): | |
| __slots__ = 'mode' | |
| def __init__(self, mode:int): | |
| super().__init__(LexerActionType.MODE) | |
| self.mode = mode | |
| # <p>This action is implemented by calling {@link Lexer#mode} with the | |
| # value provided by {@link #getMode}.</p> | |
| def execute(self, lexer:Lexer): | |
| lexer.mode(self.mode) | |
| def __hash__(self): | |
| return hash((self.actionType, self.mode)) | |
| def __eq__(self, other): | |
| if self is other: | |
| return True | |
| elif not isinstance(other, LexerModeAction): | |
| return False | |
| else: | |
| return self.mode == other.mode | |
| def __str__(self): | |
| return "mode(" + str(self.mode) + ")" | |
| # Executes a custom lexer action by calling {@link Recognizer#action} with the | |
| # rule and action indexes assigned to the custom action. The implementation of | |
| # a custom action is added to the generated code for the lexer in an override | |
| # of {@link Recognizer#action} when the grammar is compiled. | |
| # | |
| # <p>This class may represent embedded actions created with the <code>{...}</code> | |
| # syntax in ANTLR 4, as well as actions created for lexer commands where the | |
| # command argument could not be evaluated when the grammar was compiled.</p> | |
| class LexerCustomAction(LexerAction): | |
| __slots__ = ('ruleIndex', 'actionIndex') | |
| # Constructs a custom lexer action with the specified rule and action | |
| # indexes. | |
| # | |
| # @param ruleIndex The rule index to use for calls to | |
| # {@link Recognizer#action}. | |
| # @param actionIndex The action index to use for calls to | |
| # {@link Recognizer#action}. | |
| #/ | |
| def __init__(self, ruleIndex:int, actionIndex:int): | |
| super().__init__(LexerActionType.CUSTOM) | |
| self.ruleIndex = ruleIndex | |
| self.actionIndex = actionIndex | |
| self.isPositionDependent = True | |
| # <p>Custom actions are implemented by calling {@link Lexer#action} with the | |
| # appropriate rule and action indexes.</p> | |
| def execute(self, lexer:Lexer): | |
| lexer.action(None, self.ruleIndex, self.actionIndex) | |
| def __hash__(self): | |
| return hash((self.actionType, self.ruleIndex, self.actionIndex)) | |
| def __eq__(self, other): | |
| if self is other: | |
| return True | |
| elif not isinstance(other, LexerCustomAction): | |
| return False | |
| else: | |
| return self.ruleIndex == other.ruleIndex and self.actionIndex == other.actionIndex | |
| # Implements the {@code channel} lexer action by calling | |
| # {@link Lexer#setChannel} with the assigned channel. | |
| class LexerChannelAction(LexerAction): | |
| __slots__ = 'channel' | |
| # Constructs a new {@code channel} action with the specified channel value. | |
| # @param channel The channel value to pass to {@link Lexer#setChannel}. | |
| def __init__(self, channel:int): | |
| super().__init__(LexerActionType.CHANNEL) | |
| self.channel = channel | |
| # <p>This action is implemented by calling {@link Lexer#setChannel} with the | |
| # value provided by {@link #getChannel}.</p> | |
| def execute(self, lexer:Lexer): | |
| lexer._channel = self.channel | |
| def __hash__(self): | |
| return hash((self.actionType, self.channel)) | |
| def __eq__(self, other): | |
| if self is other: | |
| return True | |
| elif not isinstance(other, LexerChannelAction): | |
| return False | |
| else: | |
| return self.channel == other.channel | |
| def __str__(self): | |
| return "channel(" + str(self.channel) + ")" | |
| # This implementation of {@link LexerAction} is used for tracking input offsets | |
| # for position-dependent actions within a {@link LexerActionExecutor}. | |
| # | |
| # <p>This action is not serialized as part of the ATN, and is only required for | |
| # position-dependent lexer actions which appear at a location other than the | |
| # end of a rule. For more information about DFA optimizations employed for | |
| # lexer actions, see {@link LexerActionExecutor#append} and | |
| # {@link LexerActionExecutor#fixOffsetBeforeMatch}.</p> | |
| class LexerIndexedCustomAction(LexerAction): | |
| __slots__ = ('offset', 'action') | |
| # Constructs a new indexed custom action by associating a character offset | |
| # with a {@link LexerAction}. | |
| # | |
| # <p>Note: This class is only required for lexer actions for which | |
| # {@link LexerAction#isPositionDependent} returns {@code true}.</p> | |
| # | |
| # @param offset The offset into the input {@link CharStream}, relative to | |
| # the token start index, at which the specified lexer action should be | |
| # executed. | |
| # @param action The lexer action to execute at a particular offset in the | |
| # input {@link CharStream}. | |
| def __init__(self, offset:int, action:LexerAction): | |
| super().__init__(action.actionType) | |
| self.offset = offset | |
| self.action = action | |
| self.isPositionDependent = True | |
| # <p>This method calls {@link #execute} on the result of {@link #getAction} | |
| # using the provided {@code lexer}.</p> | |
| def execute(self, lexer:Lexer): | |
| # assume the input stream position was properly set by the calling code | |
| self.action.execute(lexer) | |
| def __hash__(self): | |
| return hash((self.actionType, self.offset, self.action)) | |
| def __eq__(self, other): | |
| if self is other: | |
| return True | |
| elif not isinstance(other, LexerIndexedCustomAction): | |
| return False | |
| else: | |
| return self.offset == other.offset and self.action == other.action | |