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 /**
44  * TODO add class description
45  */
46 class LexerATNConfig : ATNConfig
47 {
48 
49     /**
50      * @uml
51      * This is the backing field for {@link #getLexerActionExecutor}.
52      */
53     public LexerActionExecutor lexerActionExecutor;
54 
55     public bool passedThroughNonGreedyDecision;
56 
57     public this(ATNState state, int alt, PredictionContext context)
58     {
59         if (!SemanticContext.NONE) {
60             auto sp = new SemanticContext;
61             SemanticContext.NONE = sp..new SemanticContext.Predicate;
62         }
63         super(state, alt, context, SemanticContext.NONE);
64         this.passedThroughNonGreedyDecision = false;
65         this.lexerActionExecutor = null;
66     }
67 
68     public this(ATNState state, int alt, PredictionContext context, LexerActionExecutor lexerActionExecutor)
69     {
70         if (!SemanticContext.NONE) {
71             auto sp = new SemanticContext;
72             SemanticContext.NONE = sp..new SemanticContext.Predicate;
73         }
74         super(state, alt, context, SemanticContext.NONE);
75         this.lexerActionExecutor = lexerActionExecutor;
76         this.passedThroughNonGreedyDecision = false;
77     }
78 
79     public this(LexerATNConfig c, ATNState state)
80     {
81         super(c, state, c.context, c.semanticContext);
82         this.lexerActionExecutor = c.lexerActionExecutor;
83         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
84     }
85 
86     public this(LexerATNConfig c, ATNState state, LexerActionExecutor lexerActionExecutor)
87     {
88         super(c, state, c.context, c.semanticContext);
89         this.lexerActionExecutor = lexerActionExecutor;
90         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
91     }
92 
93     public this(LexerATNConfig c, ATNState state, PredictionContext context)
94     {
95         super(c, state, context, c.semanticContext);
96         this.lexerActionExecutor = c.lexerActionExecutor;
97         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
98     }
99 
100     /**
101      * @uml
102      * Gets the {@link LexerActionExecutor} capable of executing the embedded
103      *  action(s) for the current configuration.
104      */
105     public LexerActionExecutor getLexerActionExecutor()
106     {
107         return lexerActionExecutor;
108     }
109 
110     public bool hasPassedThroughNonGreedyDecision()
111     {
112         return passedThroughNonGreedyDecision;
113     }
114 
115     /**
116      * @uml
117      * @override
118      * @safe
119      * @nothrow
120      */
121     public override size_t toHash() @safe nothrow
122     {
123         size_t hashCode = MurmurHash.initialize(7);
124         hashCode = MurmurHash.update(hashCode, state.stateNumber);
125         hashCode = MurmurHash.update(hashCode, alt);
126         hashCode = MurmurHash.update(hashCode, context);
127         hashCode = MurmurHash.update(hashCode, semanticContext);
128         hashCode = MurmurHash.update(hashCode, passedThroughNonGreedyDecision ? 1 : 0);
129         hashCode = MurmurHash.update(hashCode, lexerActionExecutor);
130         hashCode = MurmurHash.finish(hashCode, 6);
131         return hashCode;
132     }
133 
134     public bool equals(ATNConfig other)
135     {
136         if (this is other) {
137             return true;
138         }
139         else if (other.classinfo != LexerATNConfig.classinfo) {
140             return false;
141         }
142 
143         LexerATNConfig lexerOther = cast(LexerATNConfig)other;
144         if (passedThroughNonGreedyDecision != lexerOther.passedThroughNonGreedyDecision) {
145             return false;
146         }
147         if (!ObjectEqualityComparator.opEquals(lexerActionExecutor, lexerOther.lexerActionExecutor)) {
148             return false;
149         }
150 
151         return super.opEquals(other);
152     }
153 
154     public static bool checkNonGreedyDecision(LexerATNConfig source, ATNState target)
155     {
156         return source.passedThroughNonGreedyDecision
157             || target.classinfo == DecisionState.classinfo && (cast(DecisionState)target).nonGreedy;
158     }
159 
160 }