1 /* 2 * Copyright (c) 2012-2020 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.ParserATNSimulator; 8 9 import antlr.v4.runtime.IntStream; 10 import antlr.v4.runtime.IntStreamConstant; 11 import antlr.v4.runtime.NoViableAltException; 12 import antlr.v4.runtime.Parser; 13 import antlr.v4.runtime.ParserRuleContext; 14 import antlr.v4.runtime.RuleContext; 15 import antlr.v4.runtime.TokenConstantDefinition; 16 import antlr.v4.runtime.TokenStream; 17 import antlr.v4.runtime.Vocabulary; 18 import antlr.v4.runtime.VocabularyImpl; 19 import antlr.v4.runtime.atn.ATN; 20 import antlr.v4.runtime.atn.ATNConfig; 21 import antlr.v4.runtime.atn.ATNConfigSet; 22 import antlr.v4.runtime.atn.ATNSimulator; 23 import antlr.v4.runtime.atn.ATNState; 24 import antlr.v4.runtime.atn.ActionTransition; 25 import antlr.v4.runtime.atn.AtomTransition; 26 import antlr.v4.runtime.atn.DecisionState; 27 import antlr.v4.runtime.atn.EpsilonTransition; 28 import antlr.v4.runtime.atn.InterfaceParserATNSimulator; 29 import antlr.v4.runtime.atn.NotSetTransition; 30 import antlr.v4.runtime.atn.PrecedencePredicateTransition; 31 import antlr.v4.runtime.atn.PredicateTransition; 32 import antlr.v4.runtime.atn.PredictionContext; 33 import antlr.v4.runtime.atn.PredictionContextCache; 34 import antlr.v4.runtime.atn.PredictionMode; 35 import antlr.v4.runtime.atn.PredictionModeConst; 36 import antlr.v4.runtime.atn.RuleStopState; 37 import antlr.v4.runtime.atn.RuleTransition; 38 import antlr.v4.runtime.atn.SemanticContext; 39 import antlr.v4.runtime.atn.SetTransition; 40 import antlr.v4.runtime.atn.SingletonPredictionContext; 41 import antlr.v4.runtime.atn.Transition; 42 import antlr.v4.runtime.atn.TransitionStates; 43 import antlr.v4.runtime.dfa.DFA; 44 import antlr.v4.runtime.dfa.DFAState; 45 import antlr.v4.runtime.dfa.PredPrediction; 46 import antlr.v4.runtime.misc; 47 import std.algorithm.searching; 48 import std.conv; 49 import std.format; 50 import std.stdio; 51 import std.typecons; 52 53 alias ATNConfigSetATNConfigSetPair = Tuple!(ATNConfigSet, "a", ATNConfigSet, "b"); 54 55 /** 56 * The embodiment of the adaptive LL(*), ALL(*), parsing strategy. 57 * 58 * <p> 59 * The basic complexity of the adaptive strategy makes it harder to understand. 60 * We begin with ATN simulation to build paths in a DFA. Subsequent prediction 61 * requests go through the DFA first. If they reach a state without an edge for 62 * the current symbol, the algorithm fails over to the ATN simulation to 63 * complete the DFA path for the current input (until it finds a conflict state 64 * or uniquely predicting state).</p> 65 * 66 * <p> 67 * All of that is done without using the outer context because we want to create 68 * a DFA that is not dependent upon the rule invocation stack when we do a 69 * prediction. One DFA works in all contexts. We avoid using context not 70 * necessarily because it's slower, although it can be, but because of the DFA 71 * caching problem. The closure routine only considers the rule invocation stack 72 * created during prediction beginning in the decision rule. For example, if 73 * prediction occurs without invoking another rule's ATN, there are no context 74 * stacks in the configurations. When lack of context leads to a conflict, we 75 * don't know if it's an ambiguity or a weakness in the strong LL(*) parsing 76 * strategy (versus full LL(*)).</p> 77 * 78 * <p> 79 * When SLL yields a configuration set with conflict, we rewind the input and 80 * retry the ATN simulation, this time using full outer context without adding 81 * to the DFA. Configuration context stacks will be the full invocation stacks 82 * from the start rule. If we get a conflict using full context, then we can 83 * definitively say we have a true ambiguity for that input sequence. If we 84 * don't get a conflict, it implies that the decision is sensitive to the outer 85 * context. (It is not context-sensitive in the sense of context-sensitive 86 * grammars.)</p> 87 * 88 * <p> 89 * The next time we reach this DFA state with an SLL conflict, through DFA 90 * simulation, we will again retry the ATN simulation using full context mode. 91 * This is slow because we can't save the results and have to "interpret" the 92 * ATN each time we get that input.</p> 93 * 94 * <p> 95 * <strong>CACHING FULL CONTEXT PREDICTIONS</strong></p> 96 * 97 * <p> 98 * We could cache results from full context to predicted alternative easily and 99 * that saves a lot of time but doesn't work in presence of predicates. The set 100 * of visible predicates from the ATN start state changes depending on the 101 * context, because closure can fall off the end of a rule. I tried to cache 102 * tuples (stack context, semantic context, predicted alt) but it was slower 103 * than interpreting and much more complicated. Also required a huge amount of 104 * memory. The goal is not to create the world's fastest parser anyway. I'd like 105 * to keep this algorithm simple. By launching multiple threads, we can improve 106 * the speed of parsing across a large number of files.</p> 107 * 108 * <p> 109 * There is no strict ordering between the amount of input used by SLL vs LL, 110 * which makes it really hard to build a cache for full context. Let's say that 111 * we have input A B C that leads to an SLL conflict with full context X. That 112 * implies that using X we might only use A B but we could also use A B C D to 113 * resolve conflict. Input A B C D could predict alternative 1 in one position 114 * in the input and A B C E could predict alternative 2 in another position in 115 * input. The conflicting SLL configurations could still be non-unique in the 116 * full context prediction, which would lead us to requiring more input than the 117 * original A B C. To make a prediction cache work, we have to track the exact 118 * input used during the previous prediction. That amounts to a cache that maps 119 * X to a specific DFA for that context.</p> 120 * 121 * <p> 122 * Something should be done for left-recursive expression predictions. They are 123 * likely LL(1) + pred eval. Easier to do the whole SLL unless error and retry 124 * with full LL thing Sam does.</p> 125 * 126 * <p> 127 * <strong>AVOIDING FULL CONTEXT PREDICTION</strong></p> 128 * 129 * <p> 130 * We avoid doing full context retry when the outer context is empty, we did not 131 * dip into the outer context by falling off the end of the decision state rule, 132 * or when we force SLL mode.</p> 133 * 134 * <p> 135 * As an example of the not dip into outer context case, consider as super 136 * constructor calls versus function calls. One grammar might look like 137 * this:</p> 138 * 139 * <pre> 140 * ctorBody 141 * : '{' superCall? stat* '}' 142 * ; 143 * </pre> 144 * 145 * <p> 146 * Or, you might see something like</p> 147 * 148 * <pre> 149 * stat 150 * : superCall ';' 151 * | expression ';' 152 * | ... 153 * ; 154 * </pre> 155 * 156 * <p> 157 * In both cases I believe that no closure operations will dip into the outer 158 * context. In the first case ctorBody in the worst case will stop at the '}'. 159 * In the 2nd case it should stop at the ';'. Both cases should stay within the 160 * entry rule and not dip into the outer context.</p> 161 * 162 * <p> 163 * <strong>PREDICATES</strong></p> 164 * 165 * <p> 166 * Predicates are always evaluated if present in either SLL or LL both. SLL and 167 * LL simulation deals with predicates differently. SLL collects predicates as 168 * it performs closure operations like ANTLR v3 did. It delays predicate 169 * evaluation until it reaches and accept state. This allows us to cache the SLL 170 * ATN simulation whereas, if we had evaluated predicates on-the-fly during 171 * closure, the DFA state configuration sets would be different and we couldn't 172 * build up a suitable DFA.</p> 173 * 174 * <p> 175 * When building a DFA accept state during ATN simulation, we evaluate any 176 * predicates and return the sole semantically valid alternative. If there is 177 * more than 1 alternative, we report an ambiguity. If there are 0 alternatives, 178 * we throw an exception. Alternatives without predicates act like they have 179 * true predicates. The simple way to think about it is to strip away all 180 * alternatives with false predicates and choose the minimum alternative that 181 * remains.</p> 182 * 183 * <p> 184 * When we start in the DFA and reach an accept state that's predicated, we test 185 * those and return the minimum semantically viable alternative. If no 186 * alternatives are viable, we throw an exception.</p> 187 * 188 * <p> 189 * During full LL ATN simulation, closure always evaluates predicates and 190 * on-the-fly. This is crucial to reducing the configuration set size during 191 * closure. It hits a landmine when parsing with the Java grammar, for example, 192 * without this on-the-fly evaluation.</p> 193 * 194 * <p> 195 * <strong>SHARING DFA</strong></p> 196 * 197 * <p> 198 * All instances of the same parser share the same decision DFAs through a 199 * static field. Each instance gets its own ATN simulator but they share the 200 * same {@link #decisionToDFA} field. They also share a 201 * {@link PredictionContextCache} object that makes sure that all 202 * {@link PredictionContext} objects are shared among the DFA states. This makes 203 * a big size difference.</p> 204 * 205 * <p> 206 * <strong>THREAD SAFETY</strong></p> 207 * 208 * <p> 209 * The {@link ParserATNSimulator} locks on the {@link #decisionToDFA} field when 210 * it adds a new DFA object to that array. {@link #addDFAEdge} 211 * locks on the DFA for the current decision when setting the 212 * {@link DFAState#edges} field. {@link #addDFAState} locks on 213 * the DFA for the current decision when looking up a DFA state to see if it 214 * already exists. We must make sure that all requests to add DFA states that 215 * are equivalent result in the same shared DFA object. This is because lots of 216 * threads will be trying to update the DFA at once. The 217 * {@link #addDFAState} method also locks inside the DFA lock 218 * but this time on the shared context cache when it rebuilds the 219 * configurations' {@link PredictionContext} objects using cached 220 * subgraphs/nodes. No other locking occurs, even during DFA simulation. This is 221 * safe as long as we can guarantee that all threads referencing 222 * {@code s.edge[t]} get the same physical target {@link DFAState}, or 223 * {@code null}. Once into the DFA, the DFA simulation does not reference the 224 * {@link DFA#states} map. It follows the {@link DFAState#edges} field to new 225 * targets. The DFA simulator will either find {@link DFAState#edges} to be 226 * {@code null}, to be non-{@code null} and {@code dfa.edges[t]} null, or 227 * {@code dfa.edges[t]} to be non-null. The 228 * {@link #addDFAEdge} method could be racing to set the field 229 * but in either case the DFA simulator works; if {@code null}, and requests ATN 230 * simulation. It could also race trying to get {@code dfa.edges[t]}, but either 231 * way it will work because it's not doing a test and set operation.</p> 232 * 233 * <p> 234 * <strong>Starting with SLL then failing to combined SLL/LL (Two-Stage 235 * Parsing)</strong></p> 236 * 237 * <p> 238 * Sam pointed out that if SLL does not give a syntax error, then there is no 239 * point in doing full LL, which is slower. We only have to try LL if we get a 240 * syntax error. For maximum speed, Sam starts the parser set to pure SLL 241 * mode with the {@link BailErrorStrategy}:</p> 242 * 243 * <pre> 244 * parser.{@link Parser#getInterpreter() getInterpreter()}.{@link #setPredictionMode setPredictionMode}{@code (}{@link PredictionMode#SLL}{@code )}; 245 * parser.{@link Parser#setErrorHandler setErrorHandler}(new {@link BailErrorStrategy}()); 246 * </pre> 247 * 248 * <p> 249 * If it does not get a syntax error, then we're done. If it does get a syntax 250 * error, we need to retry with the combined SLL/LL strategy.</p> 251 * 252 * <p> 253 * The reason this works is as follows. If there are no SLL conflicts, then the 254 * grammar is SLL (at least for that input set). If there is an SLL conflict, 255 * the full LL analysis must yield a set of viable alternatives which is a 256 * subset of the alternatives reported by SLL. If the LL set is a singleton, 257 * then the grammar is LL but not SLL. If the LL set is the same size as the SLL 258 * set, the decision is SLL. If the LL set has size > 1, then that decision 259 * is truly ambiguous on the current input. If the LL set is smaller, then the 260 * SLL conflict resolution might choose an alternative that the full LL would 261 * rule out as a possibility based upon better context information. If that's 262 * the case, then the SLL parse will definitely get an error because the full LL 263 * analysis says it's not viable. If SLL conflict resolution chooses an 264 * alternative within the LL set, them both SLL and LL would choose the same 265 * alternative because they both choose the minimum of multiple conflicting 266 * alternatives.</p> 267 * 268 * <p> 269 * Let's say we have a set of SLL conflicting alternatives {@code {1, 2, 3}} and 270 * a smaller LL set called <em>s</em>. If <em>s</em> is {@code {2, 3}}, then SLL 271 * parsing will get an error because SLL will pursue alternative 1. If 272 * <em>s</em> is {@code {1, 2}} or {@code {1, 3}} then both SLL and LL will 273 * choose the same alternative because alternative one is the minimum of either 274 * set. If <em>s</em> is {@code {2}} or {@code {3}} then SLL will get a syntax 275 * error. If <em>s</em> is {@code {1}} then SLL will succeed.</p> 276 * 277 * <p> 278 * Of course, if the input is invalid, then we will get an error for sure in 279 * both SLL and LL parsing. Erroneous input will therefore require 2 passes over 280 * the input.</p> 281 */ 282 class ParserATNSimulator : ATNSimulator, InterfaceParserATNSimulator 283 { 284 285 protected Parser parser; 286 287 public DFA[] decisionToDFA; 288 289 public PredictionModeConst mode = PredictionModeConst.LL; 290 291 /** 292 * Each prediction operation uses a cache for merge of prediction contexts. 293 * Don't keep around as it wastes huge amounts of memory. DoubleKeyMap 294 * isn't synchronized but we're ok since two threads shouldn't reuse same 295 * parser/atnsim object because it can only handle one input at a time. 296 * This maps graphs a and b to merged result c. (a,b)→c. We can avoid 297 * the merge if we ever see a and b again. Note that (b,a)→c should 298 * also be examined during cache lookup. 299 * @uml 300 * @__gshared 301 */ 302 public static __gshared DoubleKeyMap!(PredictionContext, PredictionContext, PredictionContext) mergeCache; 303 304 protected DFA _dfa; 305 306 protected TokenStream _input; 307 308 protected size_t _startIndex; 309 310 protected ParserRuleContext _outerContext; 311 312 /** 313 * @uml 314 * Testing only! 315 */ 316 protected this(ATN atn, DFA[] decisionToDFA, PredictionContextCache sharedContextCache) 317 { 318 this(null, atn, decisionToDFA, sharedContextCache); 319 } 320 321 public this(Parser parser, ATN atn, DFA[] decisionToDFA, PredictionContextCache sharedContextCache) 322 { 323 super(atn, sharedContextCache); 324 this.parser = parser; 325 this.decisionToDFA = decisionToDFA; 326 if (mergeCache is null) 327 this.mergeCache = new typeof(this.mergeCache); 328 } 329 330 /** 331 * @uml 332 * @override 333 */ 334 public override void reset() 335 { 336 } 337 338 /** 339 * @uml 340 * @override 341 */ 342 public override void clearDFA() 343 { 344 for (int d = 0; d < decisionToDFA.length; d++) { 345 decisionToDFA[d] = new DFA(atn.getDecisionState(d), d); 346 } 347 } 348 349 public int adaptivePredict(TokenStream input, int decision, ParserRuleContext outerContext) 350 { 351 debug(ParserATNSimulator) { 352 writefln("adaptivePredict decision %1$s"~ 353 " exec LA(1)==%2$s"~ 354 " line %3$s:%4$s", 355 decision, getLookaheadName(input), input.LT(1).getLine, 356 input.LT(1).getCharPositionInLine()); 357 } 358 359 _input = input; 360 _startIndex = input.index(); 361 _outerContext = outerContext; 362 DFA dfa = decisionToDFA[decision]; 363 _dfa = dfa; 364 365 size_t m = input.mark(); 366 auto index = _startIndex; 367 // Now we are certain to have a specific decision's DFA 368 // But, do we still need an initial state? 369 try { 370 DFAState s0; 371 if (dfa.isPrecedenceDfa) { 372 // the start state for a precedence DFA depends on the current 373 // parser precedence, and is provided by a DFA method. 374 s0 = dfa.getPrecedenceStartState(parser.getPrecedence()); 375 } 376 else { 377 // the start state for a "regular" DFA is just s0 378 s0 = dfa.s0; 379 } 380 381 if (!s0) { 382 if (!outerContext) 383 outerContext = ParserRuleContext.EMPTY; 384 debug(ParserATNSimulator) { 385 writefln("predictATN decision = %1$s"~ 386 " exec LA(1)==%2$s"~ 387 ", outerContext=%3$s", 388 dfa.decision, getLookaheadName(input), 389 outerContext.toString(parser)); 390 } 391 392 bool fullCtx = false; 393 ATNConfigSet s0_closure = 394 computeStartState(dfa.atnStartState, 395 ParserRuleContext.EMPTY, 396 fullCtx); 397 if (dfa.isPrecedenceDfa) { 398 /* If this is a precedence DFA, we use applyPrecedenceFilter 399 * to convert the computed start state to a precedence start 400 * state. We then use DFA.setPrecedenceStartState to set the 401 * appropriate start state for the precedence level rather 402 * than simply setting DFA.s0. 403 */ 404 dfa.s0.configs = s0_closure; // not used for prediction but useful to know start configs anyway 405 s0_closure = applyPrecedenceFilter(s0_closure); 406 s0 = addDFAState(dfa, new DFAState(s0_closure)); 407 dfa.setPrecedenceStartState(parser.getPrecedence(), s0); 408 } 409 else { 410 s0 = addDFAState(dfa, new DFAState(s0_closure)); 411 dfa.s0 = s0; 412 } 413 } 414 int alt = execATN(dfa, s0, input, index, outerContext); 415 debug(ParserATNSimulator) 416 writefln("DFA after predictATN: %1$s, alt = %s, dfa.states = %s", dfa.toString(parser.getVocabulary), alt, dfa); 417 return alt; 418 } 419 finally { 420 this.mergeCache = new typeof(this.mergeCache); // wack cache after each prediction 421 _dfa = null; 422 input.seek(to!int(index)); 423 input.release(to!int(m)); 424 } 425 } 426 427 /** 428 * There are some key conditions we're looking for after computing a new 429 * set of ATN configs (proposed DFA state): 430 * <br>- if the set is empty, there is no viable alternative for current symbol 431 * <br>- does the state uniquely predict an alternative? 432 * <br>- does the state have a conflict that would prevent us from 433 * putting it on the work list? 434 * <br><br>We also have some key operations to do: 435 * <br>- add an edge from previous DFA state to potentially new DFA state, D, 436 * upon current symbol but only if adding to work list, which means in all 437 * cases except no viable alternative (and possibly non-greedy decisions?) 438 * <br>- collecting predicates and adding semantic context to DFA accept states 439 * <br>- adding rule context to context-sensitive DFA accept states 440 * <br>- consuming an input symbol 441 * <br>- reporting a conflict 442 * <br>- reporting an ambiguity 443 * <br>- reporting a context sensitivity 444 * <br>- reporting insufficient predicates 445 * <br><br>cover these cases: 446 * <br>- dead end 447 * <br>- single alt 448 * <br>- single alt + preds 449 * <br>- conflict 450 * <br>- conflict + preds 451 */ 452 protected int execATN(DFA dfa, DFAState s0, TokenStream input, size_t startIndex, ParserRuleContext outerContext) 453 { 454 debug(ParserATNSimulator) { 455 writefln("execATN decision %1$s"~ 456 " exec LA(1)==%2$s line %3$s:%4$s", 457 dfa.decision, 458 getLookaheadName(input), 459 input.LT(1).getLine, 460 input.LT(1).getCharPositionInLine()); 461 } 462 463 DFAState previousD = s0; 464 465 debug 466 writefln("s0 = %1$s", s0); 467 468 int t = input.LA(1); 469 470 while (true) { // while more work 471 DFAState D = getExistingTargetState(previousD, t); 472 if (D is null) { 473 D = computeTargetState(dfa, previousD, t); 474 } 475 476 if (D == ERROR) { 477 // if any configs in previous dipped into outer context, that 478 // means that input up to t actually finished entry rule 479 // at least for SLL decision. Full LL doesn't dip into outer 480 // so don't need special case. 481 // We will get an error no matter what so delay until after 482 // decision; better error message. Also, no reachable target 483 // ATN states in SLL implies LL will also get nowhere. 484 // If conflict in states that dip out, choose min since we 485 // will get error no matter what. 486 NoViableAltException e = noViableAlt(input, outerContext, previousD.configs, startIndex); 487 input.seek(to!int(startIndex)); 488 int alt = getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configs, outerContext); 489 if (alt != ATN.INVALID_ALT_NUMBER) { 490 return alt; 491 } 492 throw e; 493 } 494 495 if (D.requiresFullContext && mode != PredictionModeConst.SLL) { 496 // IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error) 497 BitSet conflictingAlts = D.configs.conflictingAlts; 498 if (D.predicates != null) { 499 debug(ParserATNSimulator) 500 writeln("DFA state has preds in DFA sim LL failover"); 501 size_t conflictIndex = input.index(); 502 if (conflictIndex != startIndex) { 503 input.seek(to!int(startIndex)); 504 } 505 506 conflictingAlts = evalSemanticContext(D.predicates, outerContext, true); 507 if (conflictingAlts.cardinality ==1) { 508 debug(ParserATNSimulator) 509 writeln("Full LL avoided"); 510 return conflictingAlts.nextSetBit(0); 511 } 512 513 if (conflictIndex != startIndex) { 514 // restore the index so reporting the fallback to full 515 // context occurs with the index at the correct spot 516 input.seek(to!int(conflictIndex)); 517 } 518 } 519 520 debug(dfa_debug) 521 writefln!"ctx sensitive state %1$s in %2$s"( 522 outerContext, D); 523 bool fullCtx = true; 524 ATNConfigSet s0_closure = 525 computeStartState(dfa.atnStartState, outerContext, 526 fullCtx); 527 reportAttemptingFullContext(dfa, conflictingAlts, D.configs, startIndex, input.index()); 528 int alt = execATNWithFullContext(dfa, D, s0_closure, 529 input, startIndex, 530 outerContext); 531 return alt; 532 } 533 534 if ( D.isAcceptState ) { 535 if (D.predicates == null) { 536 return D.prediction; 537 } 538 539 auto stopIndex = input.index(); 540 input.seek(to!int(startIndex)); 541 BitSet alts = evalSemanticContext(D.predicates, outerContext, true); 542 switch (alts.cardinality) { 543 case 0: 544 throw noViableAlt(input, outerContext, D.configs, startIndex); 545 546 case 1: 547 return alts.nextSetBit(0); 548 549 default: 550 // report ambiguity after predicate evaluation to make sure the correct 551 // set of ambig alts is reported. 552 reportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configs); 553 return alts.nextSetBit(0); 554 } 555 } 556 557 previousD = D; 558 559 if (t != IntStreamConstant.EOF) { 560 input.consume(); 561 t = input.LA(1); 562 } 563 } 564 565 } 566 567 /** 568 * Get an existing target state for an edge in the DFA. If the target state 569 * for the edge has not yet been computed or is otherwise not available, 570 * this method returns {@code null}. 571 * 572 * @param previousD The current DFA state 573 * @param t The next input symbol 574 * @return The existing target DFA state for the given input symbol 575 * {@code t}, or {@code null} if the target state for this edge is not 576 * already cached 577 */ 578 public DFAState getExistingTargetState(DFAState previousD, int t) 579 { 580 DFAState[] edges = previousD.edges; 581 if (edges is null || t + 1 < 0 || t + 1 >= edges.length) { 582 return null; 583 } 584 return edges[t + 1]; 585 } 586 587 /** 588 * Compute a target state for an edge in the DFA, and attempt to add the 589 * computed state and corresponding edge to the DFA. 590 * 591 * @param dfa The DFA 592 * @param previousD The current DFA state 593 * @param t The next input symbol 594 * 595 * @return The computed target DFA state for the given input symbol 596 * {@code t}. If {@code t} does not lead to a valid DFA state, this method 597 * returns {@link #ERROR}. 598 */ 599 public DFAState computeTargetState(DFA dfa, DFAState previousD, int t) 600 { 601 ATNConfigSet reach = computeReachSet(previousD.configs, t, false); 602 if (reach is null) { 603 addDFAEdge(dfa, previousD, t, ERROR); 604 return ERROR; 605 } 606 // create new target state; we'll add to DFA after it's complete 607 DFAState D = new DFAState(reach); 608 int predictedAlt = getUniqueAlt(reach); 609 610 debug(ParserATNSimulator) { 611 BitSet[] altSubSets = PredictionMode.getConflictingAltSubsets(reach); 612 writefln("SLL altSubSets=%1$s"~ 613 ", configs=%2$s"~ 614 ", predict=%3$s, allSubsetsConflict=%4$s, "~ 615 "conflictingAlts=%5$s", 616 altSubSets, 617 reach, 618 predictedAlt, 619 PredictionMode.allSubsetsConflict(altSubSets), 620 getConflictingAlts(reach)); 621 } 622 623 if (predictedAlt != ATN.INVALID_ALT_NUMBER) { 624 // NO CONFLICT, UNIQUELY PREDICTED ALT 625 D.isAcceptState = true; 626 D.configs.uniqueAlt = predictedAlt; 627 D.prediction = predictedAlt; 628 } 629 else if ( PredictionMode.hasSLLConflictTerminatingPrediction(mode, reach)) { 630 // MORE THAN ONE VIABLE ALTERNATIVE 631 D.configs.conflictingAlts = getConflictingAlts(reach); 632 D.requiresFullContext = true; 633 // in SLL-only mode, we will stop at this state and return the minimum alt 634 D.isAcceptState = true; 635 D.prediction = D.configs.conflictingAlts.nextSetBit(0); 636 } 637 638 if ( D.isAcceptState && D.configs.hasSemanticContext ) { 639 predicateDFAState(D, atn.getDecisionState(dfa.decision)); 640 if (D.predicates != null) { 641 D.prediction = ATN.INVALID_ALT_NUMBER; 642 } 643 } 644 // all adds to dfa are done after we've created full D state 645 D = addDFAEdge(dfa, previousD, t, D); 646 return D; 647 } 648 649 public void predicateDFAState(DFAState dfaState, DecisionState decisionState) 650 { 651 // We need to test all predicates, even in DFA states that 652 // uniquely predict alternative. 653 int nalts = decisionState.getNumberOfTransitions(); 654 // Update DFA so reach becomes accept state with (predicate,alt) 655 // pairs if preds found for conflicting alts 656 BitSet altsToCollectPredsFrom = getConflictingAltsOrUniqueAlt(dfaState.configs); 657 SemanticContext[] altToPred = getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState.configs, nalts); 658 if ( altToPred !is null ) { 659 dfaState.predicates = getPredicatePredictions(altsToCollectPredsFrom, altToPred); 660 dfaState.prediction = ATN.INVALID_ALT_NUMBER; // make sure we use preds 661 } 662 else { 663 // There are preds in configs but they might go away 664 // when OR'd together like {p}? || NONE == NONE. If neither 665 // alt has preds, resolve to min alt 666 dfaState.prediction = altsToCollectPredsFrom.nextSetBit(0); 667 } 668 } 669 670 /** 671 * @uml 672 * comes back with reach.uniqueAlt set to a valid alt 673 */ 674 protected int execATNWithFullContext(DFA dfa, DFAState D, ATNConfigSet s0, TokenStream input, 675 size_t startIndex, ParserRuleContext outerContext) 676 { 677 debug(ParserATNSimulator) { 678 writefln("execATNWithFullContext %s", s0); 679 } 680 bool fullCtx = true; 681 bool foundExactAmbig = false; 682 ATNConfigSet reach = null; 683 ATNConfigSet previous = s0; 684 input.seek(to!int(startIndex)); 685 int t = input.LA(1); 686 int predictedAlt; 687 while (true) { // while more work 688 // System.out.println("LL REACH "+getLookaheadName(input)+ 689 // " from configs.size="+previous.size()+ 690 // " line "+input.LT(1).getLine()+":"+input.LT(1).getCharPositionInLine()); 691 reach = computeReachSet(previous, t, fullCtx); 692 if (reach is null) { 693 // if any configs in previous dipped into outer context, that 694 // means that input up to t actually finished entry rule 695 // at least for LL decision. Full LL doesn't dip into outer 696 // so don't need special case. 697 // We will get an error no matter what so delay until after 698 // decision; better error message. Also, no reachable target 699 // ATN states in SLL implies LL will also get nowhere. 700 // If conflict in states that dip out, choose min since we 701 // will get error no matter what. 702 NoViableAltException e = noViableAlt(input, outerContext, previous, startIndex); 703 input.seek(to!int(startIndex)); 704 int alt = getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext); 705 if ( alt!=ATN.INVALID_ALT_NUMBER ) { 706 return alt; 707 } 708 throw e; 709 } 710 711 BitSet[] altSubSets = PredictionMode.getConflictingAltSubsets(reach); 712 debug(ParserATNSimulator) { 713 writefln("LL altSubSets=%1$s, PredictionMode.getUniqueAlt(altSubSets)" ~ 714 ", resolvesToJustOneViableAlt=%3$s", 715 altSubSets, 716 PredictionMode.getUniqueAlt(altSubSets), 717 PredictionMode.resolvesToJustOneViableAlt(altSubSets)); 718 } 719 720 // System.out.println("altSubSets: "+altSubSets); 721 // System.err.println("reach="+reach+", "+reach.conflictingAlts); 722 reach.uniqueAlt = getUniqueAlt(reach); 723 // unique prediction? 724 if ( reach.uniqueAlt!=ATN.INVALID_ALT_NUMBER ) { 725 predictedAlt = reach.uniqueAlt; 726 break; 727 } 728 if ( mode != PredictionModeConst.LL_EXACT_AMBIG_DETECTION ) { 729 predictedAlt = PredictionMode.resolvesToJustOneViableAlt(altSubSets); 730 if ( predictedAlt != ATN.INVALID_ALT_NUMBER ) { 731 break; 732 } 733 } 734 else { 735 // In exact ambiguity mode, we never try to terminate early. 736 // Just keeps scarfing until we know what the conflict is 737 if ( PredictionMode.allSubsetsConflict(altSubSets) && 738 PredictionMode.allSubsetsEqual(altSubSets) ) 739 { 740 foundExactAmbig = true; 741 predictedAlt = PredictionMode.getSingleViableAlt(altSubSets); 742 break; 743 } 744 // else there are multiple non-conflicting subsets or 745 // we're not sure what the ambiguity is yet. 746 // So, keep going. 747 } 748 749 previous = reach; 750 if (t != IntStreamConstant.EOF) { 751 input.consume(); 752 t = input.LA(1); 753 } 754 } 755 756 // If the configuration set uniquely predicts an alternative, 757 // without conflict, then we know that it's a full LL decision 758 // not SLL. 759 if ( reach.uniqueAlt != ATN.INVALID_ALT_NUMBER ) { 760 reportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.index()); 761 return predictedAlt; 762 } 763 764 // We do not check predicates here because we have checked them 765 // on-the-fly when doing full context prediction. 766 767 /* 768 In non-exact ambiguity detection mode, we might actually be able to 769 detect an exact ambiguity, but I'm not going to spend the cycles 770 needed to check. We only emit ambiguity warnings in exact ambiguity 771 mode. 772 773 For example, we might know that we have conflicting configurations. 774 But, that does not mean that there is no way forward without a 775 conflict. It's possible to have nonconflicting alt subsets as in: 776 777 LL altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}] 778 779 from 780 781 [(17,1,[5 $]), (13,1,[5 10 $]), (21,1,[5 10 $]), (11,1,[$]), 782 (13,2,[5 10 $]), (21,2,[5 10 $]), (11,2,[$])] 783 784 In this case, (17,1,[5 $]) indicates there is some next sequence that 785 would resolve this without conflict to alternative 1. Any other viable 786 next sequence, however, is associated with a conflict. We stop 787 looking for input because no amount of further lookahead will alter 788 the fact that we should predict alternative 1. We just can't say for 789 sure that there is an ambiguity without looking further. 790 */ 791 reportAmbiguity(dfa, D, startIndex, input.index(), foundExactAmbig, 792 reach.getAlts(), reach); 793 794 return predictedAlt; 795 } 796 797 public ATNConfigSet computeReachSet(ATNConfigSet closure, int t, bool fullCtx) 798 { 799 debug(ParserATNSimulator) 800 writefln("in computeReachSet, starting closure: %s", closure); 801 802 if (mergeCache is null) { 803 mergeCache = new DoubleKeyMap!(PredictionContext, PredictionContext, PredictionContext); 804 } 805 806 ATNConfigSet intermediate = new ATNConfigSet(fullCtx); 807 808 /* Configurations already in a rule stop state indicate reaching the end 809 * of the decision rule (local context) or end of the start rule (full 810 * context). Once reached, these configurations are never updated by a 811 * closure operation, so they are handled separately for the performance 812 * advantage of having a smaller intermediate set when calling closure. 813 * 814 * For full-context reach operations, separate handling is required to 815 * ensure that the alternative matching the longest overall sequence is 816 * chosen when multiple such configurations can match the input. 817 */ 818 ATNConfig[] skippedStopStates; 819 820 // First figure out where we can reach on input t 821 foreach (c; closure.configs) { 822 debug(ParserATNSimulator) 823 writefln("testing %1$s at %2$s", getTokenName(t), c.toString); 824 825 if (cast(RuleStopState)c.state) { 826 assert(c.context.isEmpty); 827 if (fullCtx || t == IntStreamConstant.EOF) { 828 skippedStopStates ~= c; 829 } 830 continue; 831 } 832 833 foreach (trans; c.state.transitions) { 834 ATNState target = getReachableTarget(trans, t); 835 if (target) { 836 intermediate.add(new ATNConfig(c, target), mergeCache); 837 } 838 } 839 } 840 841 // Now figure out where the reach operation can take us... 842 843 ATNConfigSet reach = null; 844 845 /* This block optimizes the reach operation for intermediate sets which 846 * trivially indicate a termination state for the overall 847 * adaptivePredict operation. 848 * 849 * The conditions assume that intermediate 850 * contains all configurations relevant to the reach set, but this 851 * condition is not true when one or more configurations have been 852 * withheld in skippedStopStates, or when the current symbol is EOF. 853 */ 854 if (skippedStopStates is null && t != TokenConstantDefinition.EOF) { 855 if (intermediate.size() == 1 ) { 856 // Don't pursue the closure if there is just one state. 857 // It can only have one alternative; just add to result 858 // Also don't pursue the closure if there is unique alternative 859 // among the configurations. 860 reach = intermediate; 861 } 862 else if (getUniqueAlt(intermediate)!=ATN.INVALID_ALT_NUMBER ) { 863 // Also don't pursue the closure if there is unique alternative 864 // among the configurations. 865 reach = intermediate; 866 } 867 } 868 869 /* If the reach set could not be trivially determined, perform a closure 870 * operation on the intermediate set to compute its initial value. 871 */ 872 if (reach is null) { 873 reach = new ATNConfigSet(fullCtx); 874 ATNConfig[] closureBusy; 875 bool treatEofAsEpsilon = t == TokenConstantDefinition.EOF; 876 foreach (c; intermediate.configs) 877 { 878 closureATN(c, reach, closureBusy, false, fullCtx, treatEofAsEpsilon); 879 } 880 } 881 882 if (t == IntStreamConstant.EOF) { 883 /* After consuming EOF no additional input is possible, so we are 884 * only interested in configurations which reached the end of the 885 * decision rule (local context) or end of the start rule (full 886 * context). Update reach to contain only these configurations. This 887 * handles both explicit EOF transitions in the grammar and implicit 888 * EOF transitions following the end of the decision or start rule. 889 * 890 * When reach==intermediate, no closure operation was performed. In 891 * this case, removeAllConfigsNotInRuleStopState needs to check for 892 * reachable rule stop states as well as configurations already in 893 * a rule stop state. 894 * 895 * This is handled before the configurations in skippedStopStates, 896 * because any configurations potentially added from that list are 897 * already guaranteed to meet this condition whether or not it's 898 * required. 899 */ 900 reach = removeAllConfigsNotInRuleStopState(reach, reach.configs == intermediate.configs); 901 } 902 903 /* If skippedStopStates is not null, then it contains at least one 904 * configuration. For full-context reach operations, these 905 * configurations reached the end of the start rule, in which case we 906 * only add them back to reach if no configuration during the current 907 * closure operation reached such a state. This ensures adaptivePredict 908 * chooses an alternative matching the longest overall sequence when 909 * multiple alternatives are viable. 910 */ 911 if (skippedStopStates !is null && (!fullCtx || !PredictionMode.hasConfigInRuleStopState(reach))) { 912 assert(skippedStopStates.length > 0); 913 foreach (c; skippedStopStates) { 914 reach.add(c, mergeCache); 915 } 916 } 917 918 if (reach.isEmpty) 919 return null; 920 return reach; 921 } 922 923 /** 924 * Return a configuration set containing only the configurations from 925 * {@code configs} which are in a {@link RuleStopState}. If all 926 * configurations in {@code configs} are already in a rule stop state, this 927 * method simply returns {@code configs}. 928 * 929 * <p>When {@code lookToEndOfRule} is true, this method uses 930 * {@link ATN#nextTokens} for each configuration in {@code configs} which is 931 * not already in a rule stop state to see if a rule stop state is reachable 932 * from the configuration via epsilon-only transitions.</p> 933 * 934 * @param configs the configuration set to update 935 * @param lookToEndOfRule when true, this method checks for rule stop states 936 * reachable by epsilon-only transitions from each configuration in 937 * {@code configs}. 938 * 939 * @return {@code configs} if all configurations in {@code configs} are in a 940 * rule stop state, otherwise return a new configuration set containing only 941 * the configurations from {@code configs} which are in a rule stop state 942 */ 943 protected ATNConfigSet removeAllConfigsNotInRuleStopState(ATNConfigSet configs, bool lookToEndOfRule) 944 { 945 if (PredictionMode.allConfigsInRuleStopStates(configs)) { 946 return configs; 947 } 948 949 ATNConfigSet result = new ATNConfigSet(configs.fullCtx); 950 foreach (ATNConfig config; configs.configs) { 951 if (cast(RuleStopState)config.state) { 952 result.add(config, mergeCache); 953 continue; 954 } 955 956 if (lookToEndOfRule && config.state.onlyHasEpsilonTransitions()) { 957 IntervalSet nextTokens = atn.nextTokens(config.state); 958 if (nextTokens.contains(TokenConstantDefinition.EPSILON)) { 959 ATNState endOfRuleState = atn.ruleToStopState[config.state.ruleIndex]; 960 result.add(new ATNConfig(config, endOfRuleState), mergeCache); 961 } 962 } 963 } 964 return result; 965 } 966 967 public ATNConfigSet computeStartState(ATNState p, RuleContext ctx, bool fullCtx) 968 { 969 // always at least the implicit call to start rule 970 PredictionContext initialContext = PredictionContext.fromRuleContext(atn, ctx); 971 ATNConfigSet configs = new ATNConfigSet(fullCtx); 972 973 for (int i=0; i<p.getNumberOfTransitions(); i++) { 974 ATNState target = p.transition(i).target; 975 ATNConfig c = new ATNConfig(target, i+1, initialContext); 976 ATNConfig[] closureBusy; 977 closureATN(c, configs, closureBusy, true, fullCtx, false); 978 } 979 980 return configs; 981 } 982 983 public ATNConfigSet applyPrecedenceFilter(ATNConfigSet configs) 984 { 985 PredictionContext[int] statesFromAlt1; 986 ATNConfigSet configSet = new ATNConfigSet(configs.fullCtx); 987 foreach (config; configs.configs) { 988 // handle alt 1 first 989 if (config.alt != 1) { 990 continue; 991 } 992 993 SemanticContext updatedContext = config.semanticContext.evalPrecedence(parser, _outerContext); 994 if (updatedContext is null) { 995 // the configuration was eliminated 996 continue; 997 } 998 999 statesFromAlt1[config.state.stateNumber] = config.context; 1000 if (updatedContext != config.semanticContext) { 1001 configSet.add(new ATNConfig(config, updatedContext), mergeCache); 1002 } 1003 else { 1004 configSet.add(config, mergeCache); 1005 } 1006 } 1007 1008 foreach (config; configs.configs) { 1009 if (config.alt == 1) { 1010 // already handled 1011 continue; 1012 } 1013 1014 if (!config.isPrecedenceFilterSuppressed()) { 1015 /* In the future, this elimination step could be updated to also 1016 * filter the prediction context for alternatives predicting alt>1 1017 * (basically a graph subtraction algorithm). 1018 */ 1019 if (config.state.stateNumber in statesFromAlt1 && 1020 statesFromAlt1[config.state.stateNumber].opEquals(config.context)) { 1021 // eliminated 1022 continue; 1023 } 1024 } 1025 1026 configSet.add(config, mergeCache); 1027 } 1028 1029 return configSet; 1030 1031 } 1032 1033 public ATNState getReachableTarget(Transition trans, int ttype) 1034 { 1035 if (trans.matches(ttype, 0, atn.maxTokenType)) { 1036 return trans.target; 1037 } 1038 return null; 1039 } 1040 1041 public SemanticContext[] getPredsForAmbigAlts(BitSet ambigAlts, ATNConfigSet configs, 1042 int nalts) 1043 { 1044 // REACH=[1|1|[]|0:0, 1|2|[]|0:1] 1045 /* altToPred starts as an array of all null contexts. The entry at index i 1046 * corresponds to alternative i. altToPred[i] may have one of three values: 1047 * 1. null: no ATNConfig c is found such that c.alt==i 1048 * 2. SemanticContext.NONE: At least one ATNConfig c exists such that 1049 * c.alt==i and c.semanticContext==SemanticContext.NONE. In other words, 1050 * alt i has at least one unpredicated config. 1051 * 3. Non-NONE Semantic Context: There exists at least one, and for all 1052 * ATNConfig c such that c.alt==i, c.semanticContext!=SemanticContext.NONE. 1053 * 1054 * From this, it is clear that NONE||anything==NONE. 1055 */ 1056 SemanticContext[] altToPred = new SemanticContext[nalts + 1]; 1057 foreach (ATNConfig c; configs.configs) { 1058 if ( ambigAlts.get(c.alt) ) { 1059 altToPred[c.alt] = SemanticContext.or(altToPred[c.alt], c.semanticContext); 1060 } 1061 } 1062 1063 int nPredAlts = 0; 1064 if (!SemanticContext.NONE) { 1065 auto sp = new SemanticContext; 1066 SemanticContext.NONE = sp..new SemanticContext.Predicate; 1067 } 1068 for (int i = 1; i <= nalts; i++) { 1069 if (altToPred[i] is null) { 1070 altToPred[i] = SemanticContext.NONE; 1071 } 1072 else if (altToPred[i] != SemanticContext.NONE) { 1073 nPredAlts++; 1074 } 1075 } 1076 if (nPredAlts == 0) altToPred = null; 1077 debug(ParserATNSimulator) 1078 writefln("getPredsForAmbigAlts result %s", to!string(altToPred)); 1079 return altToPred; 1080 } 1081 1082 protected PredPrediction[] getPredicatePredictions(BitSet ambigAlts, SemanticContext[] altToPred) 1083 { 1084 PredPrediction[] pairs; 1085 bool containsPredicate = false; 1086 1087 for (int i = 1; i < altToPred.length; i++) { 1088 SemanticContext pred = altToPred[i]; 1089 1090 // unpredicated is indicated by SemanticContext.NONE 1091 assert(pred !is null); 1092 1093 if (ambigAlts.length > 0 && ambigAlts.get(i)) { 1094 pairs ~= new PredPrediction(pred, i); 1095 } 1096 if (pred != SemanticContext.NONE) 1097 containsPredicate = true; 1098 } 1099 1100 if (!containsPredicate) { 1101 return null; 1102 } 1103 1104 // System.out.println(Arrays.toString(altToPred)+"->"+pairs); 1105 return pairs; 1106 1107 } 1108 1109 protected int getAltThatFinishedDecisionEntryRule(ATNConfigSet configs) 1110 { 1111 IntervalSet alts = new IntervalSet(); 1112 foreach (ATNConfig c; configs.configs) { 1113 if ( c.getOuterContextDepth() > 0 || (cast(RuleStopState)c.state && c.context.hasEmptyPath) ) { 1114 alts.add(c.alt); 1115 } 1116 } 1117 if ( alts.size()==0 ) return ATN.INVALID_ALT_NUMBER; 1118 return alts.getMinElement(); 1119 } 1120 1121 /** 1122 * This method is used to improve the localization of error messages by 1123 * choosing an alternative rather than throwing a 1124 * {@link NoViableAltException} in particular prediction scenarios where the 1125 * {@link #ERROR} state was reached during ATN simulation. 1126 * 1127 * <p> 1128 * The default implementation of this method uses the following 1129 * algorithm to identify an ATN configuration which successfully parsed the 1130 * decision entry rule. Choosing such an alternative ensures that the 1131 * {@link ParserRuleContext} returned by the calling rule will be complete 1132 * and valid, and the syntax error will be reported later at a more 1133 * localized location.</p> 1134 * 1135 * <ul> 1136 * <li>If a syntactically valid path or paths reach the end of the decision rule and 1137 * they are semantically valid if predicated, return the min associated alt.</li> 1138 * <li>Else, if a semantically invalid but syntactically valid path exist 1139 * or paths exist, return the minimum associated alt. 1140 * </li> 1141 * <li>Otherwise, return {@link ATN#INVALID_ALT_NUMBER}.</li> 1142 * </ul> 1143 * 1144 * <p> 1145 * In some scenarios, the algorithm described above could predict an 1146 * alternative which will result in a {@link FailedPredicateException} in 1147 * the parser. Specifically, this could occur if the <em>only</em> configuration 1148 * capable of successfully parsing to the end of the decision rule is 1149 * blocked by a semantic predicate. By choosing this alternative within 1150 * {@link #adaptivePredict} instead of throwing a 1151 * {@link NoViableAltException}, the resulting 1152 * {@link FailedPredicateException} in the parser will identify the specific 1153 * predicate which is preventing the parser from successfully parsing the 1154 * decision rule, which helps developers identify and correct logic errors 1155 * in semantic predicates. 1156 * </p> 1157 * 1158 * @param configs The ATN configurations which were valid immediately before 1159 * the {@link #ERROR} state was reached 1160 * @param outerContext The is the \gamma_0 initial parser context from the paper 1161 * or the parser stack at the instant before prediction commences. 1162 * 1163 * @return The value to return from {@link #adaptivePredict}, or 1164 * {@link ATN#INVALID_ALT_NUMBER} if a suitable alternative was not 1165 * identified and {@link #adaptivePredict} should report an error instead. 1166 */ 1167 protected int getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(ATNConfigSet configs, 1168 ParserRuleContext outerContext) 1169 { 1170 IntervalSet alts = new IntervalSet(); 1171 foreach (ATNConfig c; configs.configs) { 1172 if (c.getOuterContextDepth > 0 || (cast(RuleStopState)c.state && c.context.hasEmptyPath) ) { 1173 alts.add(c.alt); 1174 } 1175 } 1176 if (alts.size == 0) 1177 return ATN.INVALID_ALT_NUMBER; 1178 return alts.getMinElement(); 1179 } 1180 1181 protected ATNConfigSetATNConfigSetPair splitAccordingToSemanticValidity(ATNConfigSet configs, 1182 ParserRuleContext outerContext) 1183 { 1184 ATNConfigSet succeeded = new ATNConfigSet(configs.fullCtx); 1185 ATNConfigSet failed = new ATNConfigSet(configs.fullCtx); 1186 foreach (ATNConfig c; configs.configs) { 1187 if (c.semanticContext != SemanticContext.NONE ) { 1188 bool predicateEvaluationResult = evalSemanticContext(c.semanticContext, outerContext, c.alt, configs.fullCtx); 1189 if (predicateEvaluationResult) { 1190 succeeded.add(c); 1191 } 1192 else { 1193 failed.add(c); 1194 } 1195 } 1196 else { 1197 succeeded.add(c); 1198 } 1199 } 1200 ATNConfigSetATNConfigSetPair res; 1201 res.a = succeeded; 1202 res.b = failed; 1203 return res; 1204 } 1205 1206 /** 1207 * Look through a list of predicate/alt pairs, returning alts for the 1208 * pairs that win. A {@code NONE} predicate indicates an alt containing an 1209 * unpredicated config which behaves as "always true." If !complete 1210 * then we stop at the first predicate that evaluates to true. This 1211 * includes pairs with null predicates. 1212 */ 1213 protected BitSet evalSemanticContext(PredPrediction[] predPredictions, ParserRuleContext outerContext, 1214 bool complete) 1215 { 1216 BitSet predictions; 1217 foreach (pair; predPredictions) { 1218 if (pair.pred == SemanticContext.NONE ) { 1219 predictions.set(pair.alt, true); 1220 if (!complete) { 1221 break; 1222 } 1223 continue; 1224 } 1225 1226 bool fullCtx = false; // in dfa 1227 bool predicateEvaluationResult = evalSemanticContext(pair.pred, outerContext, pair.alt, fullCtx); 1228 debug(dfa_debug) { 1229 writefln("eval pred %1$s=%2$s", pair, predicateEvaluationResult); 1230 } 1231 1232 if ( predicateEvaluationResult ) { 1233 debug(dfa_debug) 1234 writefln("PREDICT ", pair.alt); 1235 predictions.set(pair.alt, true); 1236 if (!complete) { 1237 break; 1238 } 1239 } 1240 } 1241 1242 return predictions; 1243 } 1244 1245 public bool evalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, 1246 int alt, bool fullCtx) 1247 { 1248 return pred.eval(parser, parserCallStack); 1249 } 1250 1251 protected void closureATN(ATNConfig config, ATNConfigSet configs, ref ATNConfig[] closureBusy, 1252 bool collectPredicates, bool fullCtx, bool treatEofAsEpsilon) 1253 { 1254 int initialDepth = 0; 1255 closureCheckingStopState(config, configs, closureBusy, collectPredicates, 1256 fullCtx, 1257 initialDepth, treatEofAsEpsilon); 1258 assert (!fullCtx || !configs.dipsIntoOuterContext); 1259 } 1260 1261 protected void closureCheckingStopState(ATNConfig config, ATNConfigSet configs, ref ATNConfig[] closureBusy, 1262 bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon) 1263 { 1264 debug(ParserATNSimulator) 1265 { 1266 import std.stdio : writefln; 1267 writefln!"closure(%s)"( config); 1268 } 1269 1270 if (cast(RuleStopState)config.state) { 1271 // We hit rule end. If we have context info, use it 1272 // run thru all possible stack tops in ctx 1273 if (!config.context.isEmpty) { 1274 for (int i = 0; i < config.context.size; i++) { 1275 if (config.context.getReturnState(i) == PredictionContext.EMPTY_RETURN_STATE) { 1276 if (fullCtx) { 1277 configs.add(new ATNConfig(config, config.state, 1278 cast(PredictionContext)PredictionContext.EMPTY), mergeCache); 1279 continue; 1280 } 1281 else { 1282 // we have no context info, just chase follow links (if greedy) 1283 closure_(config, configs, closureBusy, collectPredicates, 1284 fullCtx, depth, treatEofAsEpsilon); 1285 } 1286 continue; 1287 } 1288 ATNState returnState = atn.states[config.context.getReturnState(i)]; 1289 PredictionContext newContext = config.context.getParent(i); // "pop" return state 1290 ATNConfig c = new ATNConfig(returnState, config.alt, newContext, 1291 config.semanticContext); 1292 // While we have context to pop back from, we may have 1293 // gotten that context AFTER having falling off a rule. 1294 // Make sure we track that we are now out of context. 1295 // 1296 // This assignment also propagates the 1297 // isPrecedenceFilterSuppressed() value to the new 1298 // configuration. 1299 c.reachesIntoOuterContext = config.reachesIntoOuterContext; 1300 assert(depth > int.min); 1301 closureCheckingStopState(c, configs, closureBusy, collectPredicates, 1302 fullCtx, depth - 1, treatEofAsEpsilon); 1303 } 1304 return; 1305 } 1306 else if (fullCtx) { 1307 // reached end of start rule 1308 configs.add(config, mergeCache); 1309 return; 1310 } 1311 else { 1312 // else if we have no context info, just chase follow links (if greedy) 1313 debug(ParserATNSimulator) 1314 writefln("FALLING off rule %s", 1315 getRuleName(config.state.ruleIndex)); 1316 } 1317 } 1318 closure_(config, configs, closureBusy, collectPredicates, 1319 fullCtx, depth, treatEofAsEpsilon); 1320 } 1321 1322 /** 1323 * Do the actual work of walking epsilon edges 1324 */ 1325 protected void closure_(ATNConfig config, ATNConfigSet configs, ref ATNConfig[] closureBusy, 1326 bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon) 1327 { 1328 ATNState p = config.state; 1329 1330 // optimization 1331 if (!p.onlyHasEpsilonTransitions) { 1332 configs.add(config, mergeCache); 1333 // make sure to not return here, because EOF transitions can act as 1334 // both epsilon transitions and non-epsilon transitions. 1335 // if ( debug ) System.out.println("added config "+configs); 1336 } 1337 for (int i=0; i<p.getNumberOfTransitions(); i++) { 1338 if ( i==0 && canDropLoopEntryEdgeInLeftRecursiveRule(config)) 1339 continue; 1340 Transition t = p.transition(i); 1341 bool continueCollecting = 1342 collectPredicates && !(cast(ActionTransition)t); 1343 ATNConfig c = getEpsilonTarget(config, t, continueCollecting, 1344 depth == 0, fullCtx, treatEofAsEpsilon); 1345 if (c !is null) { 1346 int newDepth = depth; 1347 if (cast(RuleStopState)config.state) { 1348 assert (!fullCtx); 1349 1350 // target fell off end of rule; mark resulting c as having dipped into outer context 1351 // We can't get here if incoming config was rule stop and we had context 1352 // track how far we dip into outer context. Might 1353 // come in handy and we avoid evaluating context dependent 1354 // preds if this is > 0. 1355 if (_dfa !is null && _dfa.isPrecedenceDfa) { 1356 int outermostPrecedenceReturn = (cast(EpsilonTransition)t).outermostPrecedenceReturn; 1357 if (outermostPrecedenceReturn == _dfa.atnStartState.ruleIndex) { 1358 c.setPrecedenceFilterSuppressed(true); 1359 } 1360 } 1361 1362 c.reachesIntoOuterContext++; 1363 1364 if (count(closureBusy, c) > 0) { 1365 // avoid infinite recursion for right-recursive rules 1366 continue; 1367 } 1368 closureBusy ~= c; 1369 1370 configs.dipsIntoOuterContext = true; // TODO: can remove? only care when we add to set per middle of this method 1371 assert (newDepth > int.min); 1372 newDepth--; 1373 debug 1374 writefln("dips into outer ctx: %s", c); 1375 } 1376 else { 1377 if (!t.isEpsilon) { 1378 if (count(closureBusy, c) > 0) { 1379 // avoid infinite recursion for right-recursive rules 1380 continue; 1381 } 1382 closureBusy ~= c; 1383 } 1384 if (cast(RuleTransition)t) { 1385 // latch when newDepth goes negative - once we step out of the entry context we can't return 1386 if (newDepth >= 0) { 1387 newDepth++; 1388 } 1389 } 1390 } 1391 closureCheckingStopState(c, configs, closureBusy, continueCollecting, 1392 fullCtx, newDepth, treatEofAsEpsilon); 1393 } 1394 } 1395 1396 } 1397 1398 public string getRuleName(int index) 1399 { 1400 if (parser !is null && index>=0 ) return parser.getRuleNames()[index]; 1401 return format("<rule %s>",index); 1402 } 1403 1404 public ATNConfig getEpsilonTarget(ATNConfig config, Transition t, bool collectPredicates, 1405 bool inContext, bool fullCtx, bool treatEofAsEpsilon) 1406 { 1407 switch (t.getSerializationType()) { 1408 case TransitionStates.RULE: 1409 return ruleTransition(config, cast(RuleTransition)t); 1410 1411 case TransitionStates.PRECEDENCE: 1412 return precedenceTransition(config, cast(PrecedencePredicateTransition)t, collectPredicates, inContext, fullCtx); 1413 1414 case TransitionStates.PREDICATE: 1415 return predTransition(config, cast(PredicateTransition)t, 1416 collectPredicates, 1417 inContext, 1418 fullCtx); 1419 1420 case TransitionStates.ACTION: 1421 return actionTransition(config, cast(ActionTransition)t); 1422 1423 case TransitionStates.EPSILON: 1424 return new ATNConfig(config, t.target); 1425 1426 case TransitionStates.ATOM: 1427 case TransitionStates.RANGE: 1428 case TransitionStates.SET: 1429 // EOF transitions act like epsilon transitions after the first EOF 1430 // transition is traversed 1431 if (treatEofAsEpsilon) { 1432 if (t.matches(TokenConstantDefinition.EOF, 0, 1)) { 1433 return new ATNConfig(config, t.target); 1434 } 1435 } 1436 1437 return null; 1438 1439 default: 1440 return null; 1441 } 1442 1443 } 1444 1445 protected ATNConfig actionTransition(ATNConfig config, ActionTransition t) 1446 { 1447 debug(ParserATNSimulator) 1448 writefln!"ACTION edge %1$s:%2$s"(t.ruleIndex, t.actionIndex); 1449 return new ATNConfig(config, t.target); 1450 } 1451 1452 public ATNConfig precedenceTransition(ATNConfig config, PrecedencePredicateTransition pt, 1453 bool collectPredicates, bool inContext, bool fullCtx) 1454 { 1455 debug(ParserATNSimulator) { 1456 writefln("PRED (collectPredicates=%1$s) %2$s" ~ 1457 ">=_p, ctx dependent=true", collectPredicates, pt.precedence); 1458 if ( parser !is null ) { 1459 writefln!"context surrounding pred is %s"( 1460 parser.getRuleInvocationStack); 1461 } 1462 } 1463 1464 ATNConfig c = null; 1465 if (collectPredicates && inContext) { 1466 if ( fullCtx ) { 1467 // In full context mode, we can evaluate predicates on-the-fly 1468 // during closure, which dramatically reduces the size of 1469 // the config sets. It also obviates the need to test predicates 1470 // later during conflict resolution. 1471 size_t currentPosition = _input.index(); 1472 _input.seek(to!int(_startIndex)); 1473 bool predSucceeds = evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx); 1474 _input.seek(to!int(currentPosition)); 1475 if ( predSucceeds ) { 1476 c = new ATNConfig(config, pt.target); // no pred context 1477 } 1478 } 1479 else { 1480 SemanticContext newSemCtx = 1481 SemanticContext.and(config.semanticContext, pt.getPredicate()); 1482 c = new ATNConfig(config, pt.target, newSemCtx); 1483 } 1484 } 1485 else { 1486 c = new ATNConfig(config, pt.target); 1487 } 1488 1489 debug(ParserATNSimulator) 1490 writefln!"precedenceTransition: config from pred transition=%s"(c); 1491 return c; 1492 1493 } 1494 1495 protected ATNConfig predTransition(ATNConfig config, PredicateTransition pt, bool collectPredicates, 1496 bool inContext, bool fullCtx) 1497 { 1498 debug(ParserATNSimulator) { 1499 writefln("PRED (collectPredicates=%1$s) %2$s:%3$s, ctx dependent=%4$s", 1500 collectPredicates, pt.ruleIndex, 1501 pt.predIndex, pt.isCtxDependent); 1502 if ( parser !is null ) { 1503 writefln("context surrounding pred is %s", 1504 parser.getRuleInvocationStack()); 1505 } 1506 } 1507 1508 ATNConfig c = null; 1509 if ( collectPredicates && 1510 (!pt.isCtxDependent || (pt.isCtxDependent&&inContext)) ) 1511 { 1512 if ( fullCtx ) { 1513 // In full context mode, we can evaluate predicates on-the-fly 1514 // during closure, which dramatically reduces the size of 1515 // the config sets. It also obviates the need to test predicates 1516 // later during conflict resolution. 1517 size_t currentPosition = _input.index(); 1518 _input.seek(to!int(_startIndex)); 1519 bool predSucceeds = evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx); 1520 _input.seek(to!int(currentPosition)); 1521 if (predSucceeds) { 1522 c = new ATNConfig(config, pt.target); // no pred context 1523 } 1524 } 1525 else { 1526 SemanticContext newSemCtx = 1527 SemanticContext.and(config.semanticContext, pt.getPredicate()); 1528 c = new ATNConfig(config, pt.target, newSemCtx); 1529 } 1530 } 1531 else { 1532 c = new ATNConfig(config, pt.target); 1533 } 1534 1535 debug(ParserATNSimulator) 1536 { 1537 writefln!"config from pred transition=%s"(c); 1538 } 1539 return c; 1540 } 1541 1542 public ATNConfig ruleTransition(ATNConfig config, RuleTransition t) 1543 { 1544 debug(ParserATNSimulator) 1545 { 1546 writefln!"CALL rule %1$s, ctx=%2$s"(getRuleName(t.target.ruleIndex), config.context); 1547 } 1548 ATNState returnState = t.followState; 1549 PredictionContext newContext = 1550 SingletonPredictionContext.create(config.context, returnState.stateNumber); 1551 return new ATNConfig(config, t.target, newContext); 1552 } 1553 1554 /** 1555 * Gets a {@link BitSet} containing the alternatives in {@code configs} 1556 * which are part of one or more conflicting alternative subsets. 1557 * 1558 * @param configs The {@link ATNConfigSet} to analyze. 1559 * @return The alternatives in {@code configs} which are part of one or more 1560 * conflicting alternative subsets. If {@code configs} does not contain any 1561 * conflicting subsets, this method returns an empty {@link BitSet}. 1562 */ 1563 public BitSet getConflictingAlts(ATNConfigSet configs) 1564 { 1565 BitSet[] altsets = PredictionMode.getConflictingAltSubsets(configs); 1566 return PredictionMode.getAlts(altsets); 1567 } 1568 1569 /** 1570 * Sam pointed out a problem with the previous definition, v3, of 1571 * ambiguous states. If we have another state associated with conflicting 1572 * alternatives, we should keep going. For example, the following grammar 1573 * 1574 * s : (ID | ID ID?) ';' ; 1575 * 1576 * When the ATN simulation reaches the state before ';', it has a DFA 1577 * state that looks like: [12|1|[], 6|2|[], 12|2|[]]. Naturally 1578 * 12|1|[] and 12|2|[] conflict, but we cannot stop processing this node 1579 * because alternative to has another way to continue, via [6|2|[]]. 1580 * The key is that we have a single state that has config's only associated 1581 * with a single alternative, 2, and crucially the state transitions 1582 * among the configurations are all non-epsilon transitions. That means 1583 * we don't consider any conflicts that include alternative 2. So, we 1584 * ignore the conflict between alts 1 and 2. We ignore a set of 1585 * conflicting alts when there is an intersection with an alternative 1586 * associated with a single alt state in the state→config-list map. 1587 * 1588 * It's also the case that we might have two conflicting configurations but 1589 * also a 3rd nonconflicting configuration for a different alternative: 1590 * [1|1|[], 1|2|[], 8|3|[]]. This can come about from grammar: 1591 * 1592 * a : A | A | A B ; 1593 * 1594 * After matching input A, we reach the stop state for rule A, state 1. 1595 * State 8 is the state right before B. Clearly alternatives 1 and 2 1596 * conflict and no amount of further lookahead will separate the two. 1597 * However, alternative 3 will be able to continue and so we do not 1598 * stop working on this state. In the previous example, we're concerned 1599 * with states associated with the conflicting alternatives. Here alt 1600 * 3 is not associated with the conflicting configs, but since we can continue 1601 * looking for input reasonably, I don't declare the state done. We 1602 * ignore a set of conflicting alts when we have an alternative 1603 * that we still need to pursue. 1604 */ 1605 public BitSet getConflictingAltsOrUniqueAlt(ATNConfigSet configs) 1606 { 1607 auto conflictingAlts = new BitSet(1); 1608 if (configs.uniqueAlt != ATN.INVALID_ALT_NUMBER) { 1609 conflictingAlts.set(configs.uniqueAlt, true); 1610 } 1611 else { 1612 *conflictingAlts = configs.conflictingAlts; 1613 } 1614 return *conflictingAlts; 1615 } 1616 1617 public string getTokenName(int t) 1618 { 1619 if (t == TokenConstantDefinition.EOF) { 1620 return "EOF"; 1621 } 1622 1623 Vocabulary vocabulary = parser !is null ? parser.getVocabulary() : new VocabularyImpl(null, null, null); 1624 string displayName = vocabulary.getDisplayName(t); 1625 if (displayName == to!string(t)) { 1626 return displayName; 1627 } 1628 1629 return displayName ~ "<" ~ to!string(t) ~ ">"; 1630 } 1631 1632 public string getLookaheadName(TokenStream input) 1633 { 1634 return getTokenName(input.LA(1)); 1635 } 1636 1637 /** 1638 * Used for debugging in adaptivePredict around execATN but I cut 1639 * it out for clarity now that alg. works well. We can leave this 1640 * "dead" code for a bit. 1641 */ 1642 public void dumpDeadEndConfigs(NoViableAltException nvae) 1643 { 1644 debug 1645 writefln("dead end configs: "); 1646 foreach (ATNConfig c; nvae.getDeadEndConfigs().configs) { 1647 string trans = "no edges"; 1648 if (c.state.getNumberOfTransitions > 0) { 1649 Transition t = c.state.transition(0); 1650 if (t.classinfo == AtomTransition.classinfo) { 1651 AtomTransition at = cast(AtomTransition)t; 1652 trans = "Atom " ~ getTokenName(at._label); 1653 } 1654 else if (t.classinfo == SetTransition.classinfo) { 1655 SetTransition st = cast(SetTransition)t; 1656 bool not = (st.classinfo == NotSetTransition.classinfo); 1657 trans = (not?"~":"") ~ "Set "~ st.set.toString(); 1658 } 1659 } 1660 debug 1661 writefln("%1$s:%2$s", c.toString(parser, true), trans); 1662 } 1663 } 1664 1665 protected NoViableAltException noViableAlt(TokenStream input, ParserRuleContext outerContext, 1666 ATNConfigSet configs, size_t startIndex) 1667 { 1668 return new NoViableAltException(parser, input, 1669 input.get(to!int(startIndex)), 1670 input.LT(1), 1671 configs, outerContext); 1672 } 1673 1674 protected static int getUniqueAlt(ATNConfigSet configs) 1675 { 1676 int alt = ATN.INVALID_ALT_NUMBER; 1677 foreach (ATNConfig c; configs.configs) { 1678 if (alt == ATN.INVALID_ALT_NUMBER) { 1679 alt = c.alt; // found first alt 1680 } 1681 else if (c.alt != alt) { 1682 return ATN.INVALID_ALT_NUMBER; 1683 } 1684 } 1685 return alt; 1686 } 1687 1688 /** 1689 * Add an edge to the DFA, if possible. This method calls 1690 * {@link #addDFAState} to ensure the {@code to} state is present in the 1691 * DFA. If {@code from} is {@code null}, or if {@code t} is outside the 1692 * range of edges that can be represented in the DFA tables, this method 1693 * returns without adding the edge to the DFA. 1694 * 1695 * <p>If {@code to} is {@code null}, this method returns {@code null}. 1696 * Otherwise, this method returns the {@link DFAState} returned by calling 1697 * {@link #addDFAState} for the {@code to} state.</p> 1698 * 1699 * @param dfa The DFA 1700 * @param from The source state for the edge 1701 * @param t The input symbol 1702 * @param to The target state for the edge 1703 * 1704 * @return If {@code to} is {@code null}, this method returns {@code null}; 1705 * otherwise this method returns the result of calling {@link #addDFAState} 1706 * on {@code to} 1707 */ 1708 protected DFAState addDFAEdge(ref DFA dfa, DFAState from, size_t t, DFAState to) 1709 { 1710 debug(ParserATNSimulator) { 1711 writefln("\nEDGE %1$s -> %2$s upon %3$s", from, to, getTokenName(cast(int)t)); 1712 } 1713 if (to is null) { 1714 return null; 1715 } 1716 to = addDFAState(dfa, to); // used existing if possible not incoming 1717 if (from is null || cast(int)t < -1 || t > atn.maxTokenType) { 1718 return to; 1719 } 1720 synchronized (from) { 1721 if (from.edges == null) { 1722 from.edges = new DFAState[atn.maxTokenType+1+1]; 1723 } 1724 from.edges[t+1] = to; // connect 1725 } 1726 1727 debug(ParserATNSimulator) { 1728 writefln!"DFA =\n%s, dfa.states = %s"(dfa.decision, dfa.states); 1729 } 1730 1731 return to; 1732 } 1733 1734 /** 1735 * Add state {@code D} to the DFA if it is not already present, and return 1736 * the actual instance stored in the DFA. If a state equivalent to {@code D} 1737 * is already in the DFA, the existing state is returned. Otherwise this 1738 * method returns {@code D} after adding it to the DFA. 1739 * 1740 * <p>If {@code D} is {@link #ERROR}, this method returns {@link #ERROR} and 1741 * does not change the DFA.</p> 1742 * 1743 * @param dfa The dfa 1744 * @param D The DFA state to add 1745 * @return The state stored in the DFA. This will be either the existing 1746 * state if {@code D} is already in the DFA, or {@code D} itself if the 1747 * state was not already present. 1748 */ 1749 protected DFAState addDFAState(ref DFA dfa, DFAState D) 1750 { 1751 if (D == ERROR) 1752 return D; 1753 if (D in dfa.states) 1754 return dfa.states[D]; 1755 D.stateNumber = to!int(dfa.states.length); 1756 if (!D.configs.readonly) { 1757 D.configs.optimizeConfigs(this); 1758 D.configs.readonly(true); 1759 } 1760 dfa.states[D] = D; 1761 debug(ParserATNSimulator) 1762 writefln!"adding new DFA state: %1$s"(D); 1763 return D; 1764 } 1765 1766 protected void reportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, ATNConfigSet configs, 1767 size_t startIndex, size_t stopIndex) 1768 { 1769 debug(retry_debug) 1770 { 1771 import antlr.v4.runtime.misc.Interval; 1772 Interval interval = Interval.of(startIndex, stopIndex); 1773 writefln("reportAttemptingFullContext decision=%1$s:%2$s, input=%3$s", 1774 dfa.decision, configs, 1775 parser.getTokenStream().getText(interval)); 1776 } 1777 if (parser) 1778 parser.getErrorListenerDispatch.reportAttemptingFullContext(parser, 1779 dfa, 1780 startIndex, 1781 stopIndex, 1782 conflictingAlts, 1783 configs); 1784 } 1785 1786 protected void reportContextSensitivity(DFA dfa, int prediction, ATNConfigSet configs, 1787 size_t startIndex, size_t stopIndex) 1788 { 1789 debug(retry_debug) { 1790 import antlr.v4.runtime.misc.Interval; 1791 Interval interval = Interval.of(startIndex, stopIndex); 1792 writefln("reportContextSensitivity decision=%1$s:%2$s, input=%3$s", 1793 dfa.decision, configs, parser.getTokenStream().getText(interval)); 1794 } 1795 if (parser !is null) 1796 parser.getErrorListenerDispatch().reportContextSensitivity(parser, dfa, startIndex, stopIndex, prediction, configs); 1797 } 1798 1799 protected void reportAmbiguity(DFA dfa, DFAState D, size_t startIndex, size_t stopIndex, bool exact, 1800 BitSet ambigAlts, ATNConfigSet configs) 1801 { 1802 debug(retry_debug) { 1803 import antlr.v4.runtime.misc.Interval; 1804 Interval interval = Interval.of(startIndex, stopIndex); 1805 writefln("reportAmbiguity %1$s:%2$s, input=%3$s", 1806 ambigAlts, configs, parser.getTokenStream().getText(interval)); 1807 } 1808 if (parser !is null) parser.getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex, 1809 exact, ambigAlts, configs); 1810 } 1811 1812 public void setPredictionMode(PredictionModeConst mode) 1813 { 1814 this.mode = mode; 1815 } 1816 1817 public PredictionModeConst getPredictionMode() 1818 { 1819 return mode; 1820 } 1821 1822 public Parser getParser() 1823 { 1824 return parser; 1825 } 1826 1827 /** 1828 * TODO implementation missing 1829 */ 1830 protected bool canDropLoopEntryEdgeInLeftRecursiveRule(ATNConfig config) 1831 { 1832 auto TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT = true; 1833 if ( TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT ) 1834 return false; 1835 return false; 1836 } 1837 1838 }