1*37748cd8SNickeau<?php 2*37748cd8SNickeau 3*37748cd8SNickeaudeclare(strict_types=1); 4*37748cd8SNickeau 5*37748cd8SNickeaunamespace Antlr\Antlr4\Runtime\Atn\Actions; 6*37748cd8SNickeau 7*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Comparison\Hasher; 8*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Lexer; 9*37748cd8SNickeau 10*37748cd8SNickeau/** 11*37748cd8SNickeau * This implementation of {@see LexerAction} is used for tracking input offsets 12*37748cd8SNickeau * for position-dependent actions within a {@see LexerActionExecutor}. 13*37748cd8SNickeau * 14*37748cd8SNickeau * This action is not serialized as part of the ATN, and is only required for 15*37748cd8SNickeau * position-dependent lexer actions which appear at a location other than the 16*37748cd8SNickeau * end of a rule. For more information about DFA optimizations employed for 17*37748cd8SNickeau * lexer actions, see {@see LexerActionExecutor::append()} and 18*37748cd8SNickeau * {@see LexerActionExecutor::fixOffsetBeforeMatch()}. 19*37748cd8SNickeau * 20*37748cd8SNickeau * @author Sam Harwell 21*37748cd8SNickeau */ 22*37748cd8SNickeaufinal class LexerIndexedCustomAction implements LexerAction 23*37748cd8SNickeau{ 24*37748cd8SNickeau /** @var int */ 25*37748cd8SNickeau private $offset; 26*37748cd8SNickeau 27*37748cd8SNickeau /** @var LexerAction */ 28*37748cd8SNickeau private $action; 29*37748cd8SNickeau 30*37748cd8SNickeau /** 31*37748cd8SNickeau * Constructs a new indexed custom action by associating a character offset 32*37748cd8SNickeau * with a {@see LexerAction}. 33*37748cd8SNickeau * 34*37748cd8SNickeau * Note: This class is only required for lexer actions for which 35*37748cd8SNickeau * {@see LexerAction::isPositionDependent()} returns `true`. 36*37748cd8SNickeau * 37*37748cd8SNickeau * @param int $offset The offset into the input {@see CharStream}, 38*37748cd8SNickeau * relative to the token start index, at which 39*37748cd8SNickeau * the specified lexer action should be executed. 40*37748cd8SNickeau * @param LexerAction $action The lexer action to execute at a particular 41*37748cd8SNickeau * offset in the input {@see CharStream}. 42*37748cd8SNickeau */ 43*37748cd8SNickeau public function __construct(int $offset, LexerAction $action) 44*37748cd8SNickeau { 45*37748cd8SNickeau $this->offset = $offset; 46*37748cd8SNickeau $this->action = $action; 47*37748cd8SNickeau } 48*37748cd8SNickeau 49*37748cd8SNickeau /** 50*37748cd8SNickeau * Gets the location in the input {@see CharStream} at which the lexer 51*37748cd8SNickeau * action should be executed. The value is interpreted as an offset relative 52*37748cd8SNickeau * to the token start index. 53*37748cd8SNickeau * 54*37748cd8SNickeau * @return int The location in the input {@see CharStream} at which the lexer 55*37748cd8SNickeau * action should be executed. 56*37748cd8SNickeau */ 57*37748cd8SNickeau public function getOffset() : int 58*37748cd8SNickeau { 59*37748cd8SNickeau return $this->offset; 60*37748cd8SNickeau } 61*37748cd8SNickeau 62*37748cd8SNickeau /** 63*37748cd8SNickeau * Gets the lexer action to execute. 64*37748cd8SNickeau * 65*37748cd8SNickeau * @return LexerAction A {@see LexerAction} object which executes the lexer action. 66*37748cd8SNickeau */ 67*37748cd8SNickeau public function getAction() : LexerAction 68*37748cd8SNickeau { 69*37748cd8SNickeau return $this->action; 70*37748cd8SNickeau } 71*37748cd8SNickeau 72*37748cd8SNickeau /** 73*37748cd8SNickeau * {@inheritdoc} 74*37748cd8SNickeau * 75*37748cd8SNickeau * @return int This method returns the result of calling 76*37748cd8SNickeau * {@see LexerIndexedCustomAction::getActionType()} on the 77*37748cd8SNickeau * {@see LexerAction} returned by 78*37748cd8SNickeau * {@see LexerIndexedCustomAction::getAction()}. 79*37748cd8SNickeau */ 80*37748cd8SNickeau public function getActionType() : int 81*37748cd8SNickeau { 82*37748cd8SNickeau return $this->action->getActionType(); 83*37748cd8SNickeau } 84*37748cd8SNickeau 85*37748cd8SNickeau /** 86*37748cd8SNickeau * {@inheritdoc} 87*37748cd8SNickeau * 88*37748cd8SNickeau * @return bool This method returns `true`. 89*37748cd8SNickeau */ 90*37748cd8SNickeau public function isPositionDependent() : bool 91*37748cd8SNickeau { 92*37748cd8SNickeau return true; 93*37748cd8SNickeau } 94*37748cd8SNickeau 95*37748cd8SNickeau /** 96*37748cd8SNickeau * {@inheritdoc} 97*37748cd8SNickeau * 98*37748cd8SNickeau * This method calls {@see LexerIndexedCustomAction::execute()} on the result 99*37748cd8SNickeau * of {@see LexerIndexedCustomAction::getAction()} using the provided `lexer`. 100*37748cd8SNickeau */ 101*37748cd8SNickeau public function execute(Lexer $lexer) : void 102*37748cd8SNickeau { 103*37748cd8SNickeau // assume the input stream position was properly set by the calling code 104*37748cd8SNickeau $this->action->execute($lexer); 105*37748cd8SNickeau } 106*37748cd8SNickeau 107*37748cd8SNickeau public function hashCode() : int 108*37748cd8SNickeau { 109*37748cd8SNickeau return Hasher::hash($this->getActionType(), $this->offset, $this->action); 110*37748cd8SNickeau } 111*37748cd8SNickeau 112*37748cd8SNickeau public function equals(object $other) : bool 113*37748cd8SNickeau { 114*37748cd8SNickeau if ($this === $other) { 115*37748cd8SNickeau return true; 116*37748cd8SNickeau } 117*37748cd8SNickeau 118*37748cd8SNickeau if (!$other instanceof self) { 119*37748cd8SNickeau return false; 120*37748cd8SNickeau } 121*37748cd8SNickeau 122*37748cd8SNickeau return $this->offset === $other->offset 123*37748cd8SNickeau && $this->action->equals($other->action); 124*37748cd8SNickeau } 125*37748cd8SNickeau} 126