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 package org.antlr.v4.runtime.atn;
8 
9 import org.antlr.v4.runtime.misc.MurmurHash;
10 import org.antlr.v4.runtime.misc.ObjectEqualityComparator;
11 
12 public class LexerATNConfig extends ATNConfig {
13 	/**
14 	 * This is the backing field for {@link #getLexerActionExecutor}.
15 	 */
16 	private final LexerActionExecutor lexerActionExecutor;
17 
18 	private final boolean passedThroughNonGreedyDecision;
19 
LexerATNConfig(ATNState state, int alt, PredictionContext context)20 	public LexerATNConfig(ATNState state,
21 						  int alt,
22 						  PredictionContext context)
23 	{
24 		super(state, alt, context, SemanticContext.NONE);
25 		this.passedThroughNonGreedyDecision = false;
26 		this.lexerActionExecutor = null;
27 	}
28 
LexerATNConfig(ATNState state, int alt, PredictionContext context, LexerActionExecutor lexerActionExecutor)29 	public LexerATNConfig(ATNState state,
30 						  int alt,
31 						  PredictionContext context,
32 						  LexerActionExecutor lexerActionExecutor)
33 	{
34 		super(state, alt, context, SemanticContext.NONE);
35 		this.lexerActionExecutor = lexerActionExecutor;
36 		this.passedThroughNonGreedyDecision = false;
37 	}
38 
LexerATNConfig(LexerATNConfig c, ATNState state)39 	public LexerATNConfig(LexerATNConfig c, ATNState state) {
40 		super(c, state, c.context, c.semanticContext);
41 		this.lexerActionExecutor = c.lexerActionExecutor;
42 		this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
43 	}
44 
LexerATNConfig(LexerATNConfig c, ATNState state, LexerActionExecutor lexerActionExecutor)45 	public LexerATNConfig(LexerATNConfig c, ATNState state,
46 						  LexerActionExecutor lexerActionExecutor)
47 	{
48 		super(c, state, c.context, c.semanticContext);
49 		this.lexerActionExecutor = lexerActionExecutor;
50 		this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
51 	}
52 
LexerATNConfig(LexerATNConfig c, ATNState state, PredictionContext context)53 	public LexerATNConfig(LexerATNConfig c, ATNState state,
54 						  PredictionContext context) {
55 		super(c, state, context, c.semanticContext);
56 		this.lexerActionExecutor = c.lexerActionExecutor;
57 		this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
58 	}
59 
60 	/**
61 	 * Gets the {@link LexerActionExecutor} capable of executing the embedded
62 	 * action(s) for the current configuration.
63 	 */
getLexerActionExecutor()64 	public final LexerActionExecutor getLexerActionExecutor() {
65 		return lexerActionExecutor;
66 	}
67 
hasPassedThroughNonGreedyDecision()68 	public final boolean hasPassedThroughNonGreedyDecision() {
69 		return passedThroughNonGreedyDecision;
70 	}
71 
72 	@Override
hashCode()73 	public int hashCode() {
74 		int hashCode = MurmurHash.initialize(7);
75 		hashCode = MurmurHash.update(hashCode, state.stateNumber);
76 		hashCode = MurmurHash.update(hashCode, alt);
77 		hashCode = MurmurHash.update(hashCode, context);
78 		hashCode = MurmurHash.update(hashCode, semanticContext);
79 		hashCode = MurmurHash.update(hashCode, passedThroughNonGreedyDecision ? 1 : 0);
80 		hashCode = MurmurHash.update(hashCode, lexerActionExecutor);
81 		hashCode = MurmurHash.finish(hashCode, 6);
82 		return hashCode;
83 	}
84 
85 	@Override
equals(ATNConfig other)86 	public boolean equals(ATNConfig other) {
87 		if (this == other) {
88 			return true;
89 		}
90 		else if (!(other instanceof LexerATNConfig)) {
91 			return false;
92 		}
93 
94 		LexerATNConfig lexerOther = (LexerATNConfig)other;
95 		if (passedThroughNonGreedyDecision != lexerOther.passedThroughNonGreedyDecision) {
96 			return false;
97 		}
98 
99 		if (!ObjectEqualityComparator.INSTANCE.equals(lexerActionExecutor, lexerOther.lexerActionExecutor)) {
100 			return false;
101 		}
102 
103 		return super.equals(other);
104 	}
105 
checkNonGreedyDecision(LexerATNConfig source, ATNState target)106 	private static boolean checkNonGreedyDecision(LexerATNConfig source, ATNState target) {
107 		return source.passedThroughNonGreedyDecision
108 			|| target instanceof DecisionState && ((DecisionState)target).nonGreedy;
109 	}
110 }
111