1 /*
2  * Copyright (c) 2012-2017 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.LexerATNConfig;
8 
9 import antlr.v4.runtime.atn.ATNConfig;
10 import antlr.v4.runtime.atn.LexerActionExecutor;
11 import antlr.v4.runtime.atn.ATNState;
12 import antlr.v4.runtime.atn.DecisionState;
13 import antlr.v4.runtime.atn.PredictionContext;
14 import antlr.v4.runtime.atn.SemanticContext;
15 import antlr.v4.runtime.misc.MurmurHash;
16 import antlr.v4.runtime.misc.ObjectEqualityComparator;
17 
18 /**
19  * TODO add class description
20  */
21 class LexerATNConfig : ATNConfig
22 {
23 
24     /**
25      * This is the backing field for {@link #getLexerActionExecutor}.
26      */
27     public LexerActionExecutor lexerActionExecutor;
28 
29     public bool passedThroughNonGreedyDecision;
30 
31     public this(ATNState state, int alt, PredictionContext context)
32     {
33         if (!SemanticContext.NONE) {
34             auto sp = new SemanticContext;
35             SemanticContext.NONE = sp..new SemanticContext.Predicate;
36         }
37         super(state, alt, context, SemanticContext.NONE);
38         this.passedThroughNonGreedyDecision = false;
39         this.lexerActionExecutor = null;
40     }
41 
42     public this(ATNState state, int alt, PredictionContext context, LexerActionExecutor lexerActionExecutor)
43     {
44         if (!SemanticContext.NONE) {
45             auto sp = new SemanticContext;
46             SemanticContext.NONE = sp..new SemanticContext.Predicate;
47         }
48         super(state, alt, context, SemanticContext.NONE);
49         this.lexerActionExecutor = lexerActionExecutor;
50         this.passedThroughNonGreedyDecision = false;
51     }
52 
53     public this(LexerATNConfig c, ATNState state)
54     {
55         super(c, state, c.context, c.semanticContext);
56         this.lexerActionExecutor = c.lexerActionExecutor;
57         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
58     }
59 
60     public this(LexerATNConfig c, ATNState state, LexerActionExecutor lexerActionExecutor)
61     {
62         super(c, state, c.context, c.semanticContext);
63         this.lexerActionExecutor = lexerActionExecutor;
64         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
65     }
66 
67     public this(LexerATNConfig c, ATNState state, PredictionContext context)
68     {
69         super(c, state, context, c.semanticContext);
70         this.lexerActionExecutor = c.lexerActionExecutor;
71         this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
72     }
73 
74     /**
75      * Gets the {@link LexerActionExecutor} capable of executing the embedded
76      *  action(s) for the current configuration.
77      */
78     public LexerActionExecutor getLexerActionExecutor()
79     {
80         return lexerActionExecutor;
81     }
82 
83     public bool hasPassedThroughNonGreedyDecision()
84     {
85         return passedThroughNonGreedyDecision;
86     }
87 
88     /**
89      * @uml
90      * @override
91      * @safe
92      * @nothrow
93      */
94     public override size_t toHash() @safe nothrow
95     {
96         size_t hashCode = MurmurHash.initialize(7);
97         hashCode = MurmurHash.update(hashCode, state.stateNumber);
98         hashCode = MurmurHash.update(hashCode, alt);
99         hashCode = MurmurHash.update(hashCode, context);
100         hashCode = MurmurHash.update(hashCode, semanticContext);
101         hashCode = MurmurHash.update(hashCode, passedThroughNonGreedyDecision ? 1 : 0);
102         hashCode = MurmurHash.update(hashCode, lexerActionExecutor);
103         hashCode = MurmurHash.finish(hashCode, 6);
104         return hashCode;
105     }
106 
107     public bool equals(ATNConfig other)
108     {
109         if (this is other) {
110             return true;
111         }
112         else if (other.classinfo != LexerATNConfig.classinfo) {
113             return false;
114         }
115 
116         LexerATNConfig lexerOther = cast(LexerATNConfig)other;
117         if (passedThroughNonGreedyDecision != lexerOther.passedThroughNonGreedyDecision) {
118             return false;
119         }
120         if (!ObjectEqualityComparator.opEquals(lexerActionExecutor, lexerOther.lexerActionExecutor)) {
121             return false;
122         }
123 
124         return super.opEquals(other);
125     }
126 
127     public static bool checkNonGreedyDecision(LexerATNConfig source, ATNState target)
128     {
129         return source.passedThroughNonGreedyDecision
130             || cast(DecisionState)target && (cast(DecisionState)target).nonGreedy;
131     }
132 
133 }