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