1<?php 2 3declare(strict_types=1); 4 5namespace Antlr\Antlr4\Runtime\Error\Exceptions; 6 7use Antlr\Antlr4\Runtime\Atn\Transitions\PredicateTransition; 8use Antlr\Antlr4\Runtime\Parser; 9 10/** 11 * A semantic predicate failed during validation. Validation of predicates 12 * occurs when normally parsing the alternative just like matching a token. 13 * Disambiguating predicate evaluation occurs when we test a predicate during 14 * prediction. 15 */ 16class FailedPredicateException extends RecognitionException 17{ 18 /** @var int */ 19 private $ruleIndex; 20 21 /** @var int */ 22 private $predicateIndex; 23 24 /** @var string|null */ 25 private $predicate; 26 27 public function __construct(Parser $recognizer, string $predicate, ?string $message = null) 28 { 29 parent::__construct( 30 $recognizer, 31 $recognizer->getInputStream(), 32 $recognizer->getContext(), 33 $this->formatMessage($predicate, $message) 34 ); 35 36 $interpreter = $recognizer->getInterpreter(); 37 38 if ($interpreter === null) { 39 throw new \RuntimeException('Unexpected null interpreter.'); 40 } 41 42 $s = $interpreter->atn->states[$recognizer->getState()]; 43 44 $trans = $s->getTransition(0); 45 46 if ($trans instanceof PredicateTransition) { 47 $this->ruleIndex = $trans->ruleIndex; 48 $this->predicateIndex = $trans->predIndex; 49 } else { 50 $this->ruleIndex = 0; 51 $this->predicateIndex = 0; 52 } 53 54 $this->predicate = $predicate; 55 $this->setOffendingToken($recognizer->getCurrentToken()); 56 } 57 58 public function getRuleIndex() : int 59 { 60 return $this->ruleIndex; 61 } 62 63 public function getPredicateIndex() : int 64 { 65 return $this->predicateIndex; 66 } 67 68 public function getPredicate() : ?string 69 { 70 return $this->predicate; 71 } 72 73 public function formatMessage(string $predicate, ?string $message = null) : string 74 { 75 if ($message !== null) { 76 return $message; 77 } 78 79 return 'failed predicate: {' . $predicate . '}?'; 80 } 81} 82