1 /* 2 * Copyright (c) 2012-2020 The ANTLR Project. All rights reserved. 3 * Use of this file is governed by the BSD 3-clause license that 4 * can be found in the LICENSE.txt file in the project root. 5 */ 6 7 module antlr.v4.runtime.atn.LexerIndexedCustomAction; 8 9 import antlr.v4.runtime.atn.LexerAction; 10 import antlr.v4.runtime.atn.LexerActionType; 11 import antlr.v4.runtime.InterfaceLexer; 12 import antlr.v4.runtime.misc.MurmurHash; 13 14 /** 15 * This implementation of {@link LexerAction} is used for tracking input offsets 16 * for position-dependent actions within a {@link LexerActionExecutor}. 17 * 18 * <p>This action is not serialized as part of the ATN, and is only required for 19 * position-dependent lexer actions which appear at a location other than the 20 * end of a rule. For more information about DFA optimizations employed for 21 * lexer actions, see {@link LexerActionExecutor#append} and 22 * {@link LexerActionExecutor#fixOffsetBeforeMatch}.</p> 23 * 24 * @author Sam Harwell 25 * @since 4.2 26 */ 27 class LexerIndexedCustomAction : LexerAction 28 { 29 30 private size_t offset; 31 32 private LexerAction action; 33 34 /** 35 * @uml 36 * Constructs a new indexed custom action by associating a character offset 37 * with a {@link LexerAction}. 38 * 39 * <p>Note: This class is only required for lexer actions for which 40 * {@link LexerAction#isPositionDependent} returns {@code true}.</p> 41 * 42 * @param offset The offset into the input {@link CharStream}, relative to 43 * the token start index, at which the specified lexer action should be 44 * executed. 45 * @param action The lexer action to execute at a particular offset in the 46 * input {@link CharStream}. 47 */ 48 public this(size_t offset, LexerAction action) 49 { 50 this.offset = offset; 51 this.action = action; 52 } 53 54 /** 55 * @uml 56 * Gets the location in the input {@link CharStream} at which the lexer 57 * action should be executed. The value is interpreted as an offset relative 58 * to the token start index. 59 * 60 * @return The location in the input {@link CharStream} at which the lexer 61 * action should be executed. 62 */ 63 public size_t getOffset() 64 { 65 return offset; 66 } 67 68 /** 69 * @uml 70 * Gets the lexer action to execute. 71 * 72 * @return A {@link LexerAction} object which executes the lexer action. 73 */ 74 public LexerAction getAction() 75 { 76 return action; 77 } 78 79 /** 80 * @uml 81 * {@inheritDoc} 82 * 83 * @return This method returns the result of calling {@link #getActionType} 84 * on the {@link LexerAction} returned by {@link #getAction}. 85 */ 86 public LexerActionType getActionType() 87 { 88 return action.getActionType(); 89 } 90 91 /** 92 * @uml 93 * {@inheritDoc} 94 * @return This method returns {@code true}. 95 */ 96 public bool isPositionDependent() 97 { 98 return true; 99 } 100 101 /** 102 * @uml 103 * {@inheritDoc} 104 * 105 * <p>This method calls {@link #execute} on the result of {@link #getAction} 106 * using the provided {@code lexer}.</p> 107 */ 108 public void execute(InterfaceLexer lexer) 109 { 110 // assume the input stream position was properly set by the calling code 111 action.execute(lexer); 112 } 113 114 /** 115 * @uml 116 * @nothrow 117 * @trusted 118 * @override 119 */ 120 public override size_t toHash() @trusted nothrow 121 { 122 size_t hash = MurmurHash.initialize(); 123 hash = MurmurHash.update(hash, offset); 124 hash = MurmurHash.update!LexerAction(hash, action); 125 return MurmurHash.finish(hash, 2); 126 } 127 128 public bool equals(Object obj) 129 { 130 if (obj is this) { 131 return true; 132 } 133 else if (!cast(LexerIndexedCustomAction)obj) { 134 return false; 135 } 136 LexerIndexedCustomAction other = cast(LexerIndexedCustomAction)obj; 137 return offset == other.getOffset 138 && action == other.getAction; 139 } 140 141 }