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 // Class LexerCustomAction
42 /**
43  * @uml
44  * Executes a custom lexer action by calling {@link Recognizer#action} with the
45  * rule and action indexes assigned to the custom action. The implementation of
46  * a custom action is added to the generated code for the lexer in an override
47  * of {@link Recognizer#action} when the grammar is compiled.
48  *
49  * <p>This class may represent embedded actions created with the <code>{...}</code>
50  * syntax in ANTLR 4, as well as actions created for lexer commands where the
51  * command argument could not be evaluated when the grammar was compiled.</p>
52  */
53 class LexerCustomAction : LexerAction
54 {
55 
56     public int ruleIndex;
57 
58     public int actionIndex;
59 
60     /**
61      * @uml
62      * Constructs a custom lexer action with the specified rule and action
63      * indexes.
64      *
65      *  @param ruleIndex The rule index to use for calls to
66      *  {@link Recognizer#action}.
67      *  @param actionIndex The action index to use for calls to
68      *  {@link Recognizer#action}.
69      */
70     public this(int ruleIndex, int actionIndex)
71     {
72         this.ruleIndex = ruleIndex;
73         this.actionIndex = actionIndex;
74     }
75 
76     public int getRuleIndex()
77     {
78         return ruleIndex;
79     }
80 
81     public int getActionIndex()
82     {
83         return actionIndex;
84     }
85 
86     /**
87      * @uml
88      * This method returns {@link LexerActionType#CUSTOM}.
89      * @safe
90      * @nothrow
91      */
92     public LexerActionType getActionType() @safe nothrow
93     {
94         return LexerActionType.CUSTOM;
95     }
96 
97     /**
98      * @uml
99      * @override
100      * Gets whether the lexer action is position-dependent. Position-dependent
101      * actions may have different semantics depending on the {@link CharStream}
102      * index at the time the action is executed
103      * <p>Custom actions are position-dependent since they may represent a
104      * user-defined embedded action which makes calls to methods like
105      * {@link Lexer#getText}.</p>
106      *
107      *  @return This method returns {@code true}.
108      */
109     public override bool isPositionDependent()
110     {
111         return true;
112     }
113 
114     /**
115      * @uml
116      * @override
117      * <p>Custom actions are implemented by calling {@link Lexer#action} with the
118      * appropriate rule and action indexes.</p>
119      */
120     public override void execute(InterfaceLexer lexer)
121     {
122         lexer.action(null, ruleIndex, actionIndex);
123     }
124 
125     /**
126      * @uml
127      * @safe
128      * @nothrow
129      * @override
130      */
131     public override size_t toHash() @safe nothrow
132     {
133         size_t hash = MurmurHash.initialize();
134         hash = MurmurHash.update(hash, Utils.rank(getActionType));
135         hash = MurmurHash.update(hash, ruleIndex);
136         hash = MurmurHash.update(hash, actionIndex);
137         return MurmurHash.finish(hash, 3);
138 
139     }
140 
141     public bool equals(Object obj)
142     {
143 	if (obj is this) {
144             return true;
145         }
146         else if (obj.classinfo != LexerCustomAction.classinfo) {
147             return false;
148         }
149         LexerCustomAction other = cast(LexerCustomAction)obj;
150         return ruleIndex == other.ruleIndex
151             && actionIndex == other.actionIndex;
152     }
153 
154 }