File: //lib/mysqlsh/lib/python3.8/site-packages/antlr4/error/DiagnosticErrorListener.py
#
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
# Use of this file is governed by the BSD 3-clause license that
# can be found in the LICENSE.txt file in the project root.
#
#
# This implementation of {@link ANTLRErrorListener} can be used to identify
# certain potential correctness and performance problems in grammars. "Reports"
# are made by calling {@link Parser#notifyErrorListeners} with the appropriate
# message.
#
# <ul>
# <li><b>Ambiguities</b>: These are cases where more than one path through the
# grammar can match the input.</li>
# <li><b>Weak context sensitivity</b>: These are cases where full-context
# prediction resolved an SLL conflict to a unique alternative which equaled the
# minimum alternative of the SLL conflict.</li>
# <li><b>Strong (forced) context sensitivity</b>: These are cases where the
# full-context prediction resolved an SLL conflict to a unique alternative,
# <em>and</em> the minimum alternative of the SLL conflict was found to not be
# a truly viable alternative. Two-stage parsing cannot be used for inputs where
# this situation occurs.</li>
# </ul>
from io import StringIO
from antlr4 import Parser, DFA
from antlr4.atn.ATNConfigSet import ATNConfigSet
from antlr4.error.ErrorListener import ErrorListener
class DiagnosticErrorListener(ErrorListener):
def __init__(self, exactOnly:bool=True):
# whether all ambiguities or only exact ambiguities are reported.
self.exactOnly = exactOnly
def reportAmbiguity(self, recognizer:Parser, dfa:DFA, startIndex:int,
stopIndex:int, exact:bool, ambigAlts:set, configs:ATNConfigSet):
if self.exactOnly and not exact:
return
with StringIO() as buf:
buf.write("reportAmbiguity d=")
buf.write(self.getDecisionDescription(recognizer, dfa))
buf.write(": ambigAlts=")
buf.write(str(self.getConflictingAlts(ambigAlts, configs)))
buf.write(", input='")
buf.write(recognizer.getTokenStream().getText(startIndex, stopIndex))
buf.write("'")
recognizer.notifyErrorListeners(buf.getvalue())
def reportAttemptingFullContext(self, recognizer:Parser, dfa:DFA, startIndex:int,
stopIndex:int, conflictingAlts:set, configs:ATNConfigSet):
with StringIO() as buf:
buf.write("reportAttemptingFullContext d=")
buf.write(self.getDecisionDescription(recognizer, dfa))
buf.write(", input='")
buf.write(recognizer.getTokenStream().getText(startIndex, stopIndex))
buf.write("'")
recognizer.notifyErrorListeners(buf.getvalue())
def reportContextSensitivity(self, recognizer:Parser, dfa:DFA, startIndex:int,
stopIndex:int, prediction:int, configs:ATNConfigSet):
with StringIO() as buf:
buf.write("reportContextSensitivity d=")
buf.write(self.getDecisionDescription(recognizer, dfa))
buf.write(", input='")
buf.write(recognizer.getTokenStream().getText(startIndex, stopIndex))
buf.write("'")
recognizer.notifyErrorListeners(buf.getvalue())
def getDecisionDescription(self, recognizer:Parser, dfa:DFA):
decision = dfa.decision
ruleIndex = dfa.atnStartState.ruleIndex
ruleNames = recognizer.ruleNames
if ruleIndex < 0 or ruleIndex >= len(ruleNames):
return str(decision)
ruleName = ruleNames[ruleIndex]
if ruleName is None or len(ruleName)==0:
return str(decision)
return str(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 reportedAlts The set of conflicting or ambiguous alternatives, as
# reported by the parser.
# @param configs The conflicting or ambiguous configuration set.
# @return Returns {@code reportedAlts} if it is not {@code null}, otherwise
# returns the set of alternatives represented in {@code configs}.
#
def getConflictingAlts(self, reportedAlts:set, configs:ATNConfigSet):
if reportedAlts is not None:
return reportedAlts
result = set()
for config in configs:
result.add(config.alt)
return result