# # 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): 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}. # #
The {@code skip} command does not have any parameters, so this action is # implemented as a singleton instance exposed by {@link #INSTANCE}.
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): 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): def __init__(self, mode:int): super().__init__(LexerActionType.PUSH_MODE) self.mode = mode #This action is implemented by calling {@link Lexer#pushMode} with the # value provided by {@link #getMode}.
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}. # #The {@code popMode} command does not have any parameters, so this action is # implemented as a singleton instance exposed by {@link #INSTANCE}.
class LexerPopModeAction(LexerAction): INSTANCE = None def __init__(self): super().__init__(LexerActionType.POP_MODE) #This action is implemented by calling {@link Lexer#popMode}.
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}. # #The {@code more} command does not have any parameters, so this action is # implemented as a singleton instance exposed by {@link #INSTANCE}.
class LexerMoreAction(LexerAction): INSTANCE = None def __init__(self): super().__init__(LexerActionType.MORE) #This action is implemented by calling {@link Lexer#popMode}.
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): def __init__(self, mode:int): super().__init__(LexerActionType.MODE) self.mode = mode #This action is implemented by calling {@link Lexer#mode} with the # value provided by {@link #getMode}.
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. # #This class may represent embedded actions created with the {...}
# 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.
Custom actions are implemented by calling {@link Lexer#action} with the # appropriate rule and action indexes.
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): # 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 #This action is implemented by calling {@link Lexer#setChannel} with the # value provided by {@link #getChannel}.
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}. # #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}.
class LexerIndexedCustomAction(LexerAction): # Constructs a new indexed custom action by associating a character offset # with a {@link LexerAction}. # #Note: This class is only required for lexer actions for which # {@link LexerAction#isPositionDependent} returns {@code true}.
# # @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 #This method calls {@link #execute} on the result of {@link #getAction} # using the provided {@code lexer}.
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