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 }