1 /*
2  * [The "BSD license"]
3  *  Copyright (c) 2016 Terence Parr
4  *  Copyright (c) 2016 Sam Harwell
5  *  Copyright (c) 2017 Egbert Voigt
6  *  All rights reserved.
7  *
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions
10  *  are met:
11  *
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. The name of the author may not be used to endorse or promote products
18  *     derived from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 module antlr.v4.runtime.atn.LexerATNConfig;
33 
34 import antlr.v4.runtime.atn.ATNConfig;
35 import antlr.v4.runtime.atn.LexerActionExecutor;
36 import antlr.v4.runtime.atn.ATNState;
37 import antlr.v4.runtime.atn.DecisionState;
38 import antlr.v4.runtime.atn.PredictionContext;
39 import antlr.v4.runtime.atn.SemanticContext;
40 import antlr.v4.runtime.misc.MurmurHash;
41 import antlr.v4.runtime.misc.ObjectEqualityComparator;
42 
43 // Class LexerATNConfig
44 /**
45  * TODO add class description
46  */
47 class LexerATNConfig : ATNConfig
48 {
49 
50     /**
51      * @uml
52      * This is the backing field for {@link #getLexerActionExecutor}.
53      */
54     public LexerActionExecutor lexerActionExecutor;
55 
56     public bool passedThroughNonGreedyDecision;
57 
58     public this(ATNState state, int alt, PredictionContext context)
59     {
60         super(state, alt, context, SemanticContext.NONE);
61         this.passedThroughNonGreedyDecision = false;
62         this.lexerActionExecutor = null;
63     }
64 
65     public this(ATNState state, int alt, PredictionContext context, LexerActionExecutor lexerActionExecutor)
66     {
67         super(state, alt, context, SemanticContext.NONE);
68         this.lexerActionExecutor = lexerActionExecutor;
69         this.passedThroughNonGreedyDecision = false;
70     }
71 
72     public this(LexerATNConfig c, ATNState state)
73     {
74         super(c, state, c.context, c.semanticContext);
75         this.lexerActionExecutor = c.lexerActionExecutor;
76         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
77     }
78 
79     public this(LexerATNConfig c, ATNState state, LexerActionExecutor lexerActionExecutor)
80     {
81         super(c, state, c.context, c.semanticContext);
82         this.lexerActionExecutor = lexerActionExecutor;
83         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
84     }
85 
86     public this(LexerATNConfig c, ATNState state, PredictionContext context)
87     {
88         super(c, state, context, c.semanticContext);
89         this.lexerActionExecutor = c.lexerActionExecutor;
90         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
91     }
92 
93     /**
94      * @uml
95      * Gets the {@link LexerActionExecutor} capable of executing the embedded
96      *  action(s) for the current configuration.
97      */
98     public LexerActionExecutor getLexerActionExecutor()
99     {
100         return lexerActionExecutor;
101     }
102 
103     public bool hasPassedThroughNonGreedyDecision()
104     {
105         return passedThroughNonGreedyDecision;
106     }
107 
108     /**
109      * @uml
110      * @override
111      * @safe
112      * @nothrow
113      */
114     public override size_t toHash() @safe nothrow
115     {
116         size_t hashCode = MurmurHash.initialize(7);
117         hashCode = MurmurHash.update(hashCode, state.stateNumber);
118         hashCode = MurmurHash.update(hashCode, alt);
119         hashCode = MurmurHash.update(hashCode, context);
120         hashCode = MurmurHash.update(hashCode, semanticContext);
121         hashCode = MurmurHash.update(hashCode, passedThroughNonGreedyDecision ? 1 : 0);
122         hashCode = MurmurHash.update(hashCode, lexerActionExecutor);
123         hashCode = MurmurHash.finish(hashCode, 6);
124         return hashCode;
125     }
126 
127     public bool equals(ATNConfig other)
128     {
129         if (this is other) {
130             return true;
131         }
132         else if (other.classinfo != LexerATNConfig.classinfo) {
133             return false;
134         }
135 
136         LexerATNConfig lexerOther = cast(LexerATNConfig)other;
137         if (passedThroughNonGreedyDecision != lexerOther.passedThroughNonGreedyDecision) {
138             return false;
139         }
140         if (!ObjectEqualityComparator.opEquals(lexerActionExecutor, lexerOther.lexerActionExecutor)) {
141             return false;
142         }
143 
144         return super.opEquals(other);
145     }
146 
147     public static bool checkNonGreedyDecision(LexerATNConfig source, ATNState target)
148     {
149         return source.passedThroughNonGreedyDecision
150             || target.classinfo == DecisionState.classinfo && (cast(DecisionState)target).nonGreedy;
151     }
152 
153 }