1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2013 Terence Parr 4 * Copyright (c) 2013 Sam Harwell 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 module antlr.v4.runtime.atn.LexerCustomAction; 32 33 import std.traits; 34 import std.conv; 35 import antlr.v4.runtime.atn.LexerAction; 36 import antlr.v4.runtime.atn.LexerActionType; 37 import antlr.v4.runtime.InterfaceLexer; 38 import antlr.v4.runtime.misc.MurmurHash; 39 import antlr.v4.runtime.misc.Utils; 40 41 /** 42 * @uml 43 * Executes a custom lexer action by calling {@link Recognizer#action} with the 44 * rule and action indexes assigned to the custom action. The implementation of 45 * a custom action is added to the generated code for the lexer in an override 46 * of {@link Recognizer#action} when the grammar is compiled. 47 * 48 * <p>This class may represent embedded actions created with the <code>{...}</code> 49 * syntax in ANTLR 4, as well as actions created for lexer commands where the 50 * command argument could not be evaluated when the grammar was compiled.</p> 51 */ 52 class LexerCustomAction : LexerAction 53 { 54 55 public int ruleIndex; 56 57 public int actionIndex; 58 59 /** 60 * @uml 61 * Constructs a custom lexer action with the specified rule and action 62 * indexes. 63 * 64 * @param ruleIndex The rule index to use for calls to 65 * {@link Recognizer#action}. 66 * @param actionIndex The action index to use for calls to 67 * {@link Recognizer#action}. 68 */ 69 public this(int ruleIndex, int actionIndex) 70 { 71 this.ruleIndex = ruleIndex; 72 this.actionIndex = actionIndex; 73 } 74 75 public int getRuleIndex() 76 { 77 return ruleIndex; 78 } 79 80 public int getActionIndex() 81 { 82 return actionIndex; 83 } 84 85 /** 86 * @uml 87 * This method returns {@link LexerActionType#CUSTOM}. 88 * @safe 89 * @nothrow 90 */ 91 public LexerActionType getActionType() @safe nothrow 92 { 93 return LexerActionType.CUSTOM; 94 } 95 96 /** 97 * @uml 98 * @override 99 * Gets whether the lexer action is position-dependent. Position-dependent 100 * actions may have different semantics depending on the {@link CharStream} 101 * index at the time the action is executed 102 * <p>Custom actions are position-dependent since they may represent a 103 * user-defined embedded action which makes calls to methods like 104 * {@link Lexer#getText}.</p> 105 * 106 * @return This method returns {@code true}. 107 */ 108 public override bool isPositionDependent() 109 { 110 return true; 111 } 112 113 /** 114 * @uml 115 * @override 116 * <p>Custom actions are implemented by calling {@link Lexer#action} with the 117 * appropriate rule and action indexes.</p> 118 */ 119 public override void execute(InterfaceLexer lexer) 120 { 121 lexer.action(null, ruleIndex, actionIndex); 122 } 123 124 /** 125 * @uml 126 * @safe 127 * @nothrow 128 * @override 129 */ 130 public override size_t toHash() @safe nothrow 131 { 132 size_t hash = MurmurHash.initialize(); 133 hash = MurmurHash.update(hash, Utils.rank(getActionType)); 134 hash = MurmurHash.update(hash, ruleIndex); 135 hash = MurmurHash.update(hash, actionIndex); 136 return MurmurHash.finish(hash, 3); 137 138 } 139 140 public bool equals(Object obj) 141 { 142 if (obj is this) { 143 return true; 144 } 145 else if (obj.classinfo != LexerCustomAction.classinfo) { 146 return false; 147 } 148 LexerCustomAction other = cast(LexerCustomAction)obj; 149 return ruleIndex == other.ruleIndex 150 && actionIndex == other.actionIndex; 151 } 152 153 }