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 }