1 /* 2 * Copyright (c) 2012-2017 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 package org.antlr.v4.runtime.atn; 8 9 import org.antlr.v4.runtime.CharStream; 10 import org.antlr.v4.runtime.Lexer; 11 import org.antlr.v4.runtime.Recognizer; 12 import org.antlr.v4.runtime.misc.MurmurHash; 13 14 /** 15 * Executes a custom lexer action by calling {@link Recognizer#action} with the 16 * rule and action indexes assigned to the custom action. The implementation of 17 * a custom action is added to the generated code for the lexer in an override 18 * of {@link Recognizer#action} when the grammar is compiled. 19 * 20 * <p>This class may represent embedded actions created with the <code>{...}</code> 21 * syntax in ANTLR 4, as well as actions created for lexer commands where the 22 * command argument could not be evaluated when the grammar was compiled.</p> 23 * 24 * @author Sam Harwell 25 * @since 4.2 26 */ 27 public final class LexerCustomAction implements LexerAction { 28 private final int ruleIndex; 29 private final int actionIndex; 30 31 /** 32 * Constructs a custom lexer action with the specified rule and action 33 * indexes. 34 * 35 * @param ruleIndex The rule index to use for calls to 36 * {@link Recognizer#action}. 37 * @param actionIndex The action index to use for calls to 38 * {@link Recognizer#action}. 39 */ LexerCustomAction(int ruleIndex, int actionIndex)40 public LexerCustomAction(int ruleIndex, int actionIndex) { 41 this.ruleIndex = ruleIndex; 42 this.actionIndex = actionIndex; 43 } 44 45 /** 46 * Gets the rule index to use for calls to {@link Recognizer#action}. 47 * 48 * @return The rule index for the custom action. 49 */ getRuleIndex()50 public int getRuleIndex() { 51 return ruleIndex; 52 } 53 54 /** 55 * Gets the action index to use for calls to {@link Recognizer#action}. 56 * 57 * @return The action index for the custom action. 58 */ getActionIndex()59 public int getActionIndex() { 60 return actionIndex; 61 } 62 63 /** 64 * {@inheritDoc} 65 * 66 * @return This method returns {@link LexerActionType#CUSTOM}. 67 */ 68 @Override getActionType()69 public LexerActionType getActionType() { 70 return LexerActionType.CUSTOM; 71 } 72 73 /** 74 * Gets whether the lexer action is position-dependent. Position-dependent 75 * actions may have different semantics depending on the {@link CharStream} 76 * index at the time the action is executed. 77 * 78 * <p>Custom actions are position-dependent since they may represent a 79 * user-defined embedded action which makes calls to methods like 80 * {@link Lexer#getText}.</p> 81 * 82 * @return This method returns {@code true}. 83 */ 84 @Override isPositionDependent()85 public boolean isPositionDependent() { 86 return true; 87 } 88 89 /** 90 * {@inheritDoc} 91 * 92 * <p>Custom actions are implemented by calling {@link Lexer#action} with the 93 * appropriate rule and action indexes.</p> 94 */ 95 @Override execute(Lexer lexer)96 public void execute(Lexer lexer) { 97 lexer.action(null, ruleIndex, actionIndex); 98 } 99 100 @Override hashCode()101 public int hashCode() { 102 int hash = MurmurHash.initialize(); 103 hash = MurmurHash.update(hash, getActionType().ordinal()); 104 hash = MurmurHash.update(hash, ruleIndex); 105 hash = MurmurHash.update(hash, actionIndex); 106 return MurmurHash.finish(hash, 3); 107 } 108 109 @Override equals(Object obj)110 public boolean equals(Object obj) { 111 if (obj == this) { 112 return true; 113 } 114 else if (!(obj instanceof LexerCustomAction)) { 115 return false; 116 } 117 118 LexerCustomAction other = (LexerCustomAction)obj; 119 return ruleIndex == other.ruleIndex 120 && actionIndex == other.actionIndex; 121 } 122 } 123