exactOnly = $exactOnly; } public function reportAmbiguity( Parser $recognizer, DFA $dfa, int $startIndex, int $stopIndex, bool $exact, ?BitSet $ambigAlts, ATNConfigSet $configs ) : void { if ($this->exactOnly && !$exact) { return; } $tokenStream = $recognizer->getTokenStream(); $msg = \sprintf( 'reportAmbiguity d=%s: ambigAlts=%s, input=\'%s\'', $this->getDecisionDescription($recognizer, $dfa), $this->getConflictingAlts($ambigAlts, $configs), $tokenStream === null ? '' : $tokenStream->getTextByInterval(new Interval($startIndex, $stopIndex)) ); $recognizer->notifyErrorListeners($msg); } public function reportAttemptingFullContext( Parser $recognizer, DFA $dfa, int $startIndex, int $stopIndex, ?BitSet $conflictingAlts, ATNConfigSet $configs ) : void { $tokenStream = $recognizer->getTokenStream(); $msg = \sprintf( 'reportAttemptingFullContext d=%s, input=\'%s\'', $this->getDecisionDescription($recognizer, $dfa), $tokenStream === null ? '' : $tokenStream->getTextByInterval(new Interval($startIndex, $stopIndex)) ); $recognizer->notifyErrorListeners($msg); } public function reportContextSensitivity( Parser $recognizer, DFA $dfa, int $startIndex, int $stopIndex, int $prediction, ATNConfigSet $configs ) : void { $tokenStream = $recognizer->getTokenStream(); $msg = \sprintf( 'reportContextSensitivity d=%s, input=\'%s\'', $this->getDecisionDescription($recognizer, $dfa), $tokenStream === null ? '' : $tokenStream->getTextByInterval(new Interval($startIndex, $stopIndex)) ); $recognizer->notifyErrorListeners($msg); } protected function getDecisionDescription(Parser $recognizer, DFA $dfa) : string { $decision = $dfa->decision; if ($dfa->atnStartState === null) { throw new \RuntimeException('Unexpected null ATN Start State.'); } $ruleIndex = $dfa->atnStartState->ruleIndex; $ruleNames = $recognizer->getRuleNames(); if ($ruleIndex < 0 || $ruleIndex >= \count($ruleNames)) { return (string) $decision; } $ruleName = $ruleNames[$ruleIndex]; if (\strlen($ruleName) === 0) { return (string) $decision; } return \sprintf('%d (%s)', $decision, $ruleName); } /** * Computes the set of conflicting or ambiguous alternatives from a * configuration set, if that information was not already provided by the * parser. * * @param BitSet|null $reportedAlts The set of conflicting or ambiguous * alternatives, as reported by the parser. * @param ATNConfigSet $configs The conflicting or ambiguous * configuration set. * * @return BitSet `reportedAlts` if it is not `null`, otherwise returns * the set of alternatives represented in `configs`. */ protected function getConflictingAlts(?BitSet $reportedAlts, ATNConfigSet $configs) : BitSet { if ($reportedAlts !== null) { return $reportedAlts; } $result = new BitSet(); foreach ($configs->configs as $config) { $result->add($config->alt); } return $result; } }