| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #
- # 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.
- #
- from antlr4.RuleContext import RuleContext
- from antlr4.Token import Token
- from antlr4.error.ErrorListener import ProxyErrorListener, ConsoleErrorListener
- # need forward delcaration
- RecognitionException = None
- class Recognizer(object):
- __slots__ = ('_listeners', '_interp', '_stateNumber')
- tokenTypeMapCache = dict()
- ruleIndexMapCache = dict()
- def __init__(self):
- self._listeners = [ ConsoleErrorListener.INSTANCE ]
- self._interp = None
- self._stateNumber = -1
- def extractVersion(self, version):
- pos = version.find(".")
- major = version[0:pos]
- version = version[pos+1:]
- pos = version.find(".")
- if pos==-1:
- pos = version.find("-")
- if pos==-1:
- pos = len(version)
- minor = version[0:pos]
- return major, minor
- def checkVersion(self, toolVersion):
- runtimeVersion = "4.9.3"
- rvmajor, rvminor = self.extractVersion(runtimeVersion)
- tvmajor, tvminor = self.extractVersion(toolVersion)
- if rvmajor!=tvmajor or rvminor!=tvminor:
- print("ANTLR runtime and generated code versions disagree: "+runtimeVersion+"!="+toolVersion)
- def addErrorListener(self, listener):
- self._listeners.append(listener)
- def removeErrorListener(self, listener):
- self._listeners.remove(listener)
- def removeErrorListeners(self):
- self._listeners = []
- def getTokenTypeMap(self):
- tokenNames = self.getTokenNames()
- if tokenNames is None:
- from antlr4.error.Errors import UnsupportedOperationException
- raise UnsupportedOperationException("The current recognizer does not provide a list of token names.")
- result = self.tokenTypeMapCache.get(tokenNames, None)
- if result is None:
- result = zip( tokenNames, range(0, len(tokenNames)))
- result["EOF"] = Token.EOF
- self.tokenTypeMapCache[tokenNames] = result
- return result
- # Get a map from rule names to rule indexes.
- #
- # <p>Used for XPath and tree pattern compilation.</p>
- #
- def getRuleIndexMap(self):
- ruleNames = self.getRuleNames()
- if ruleNames is None:
- from antlr4.error.Errors import UnsupportedOperationException
- raise UnsupportedOperationException("The current recognizer does not provide a list of rule names.")
- result = self.ruleIndexMapCache.get(ruleNames, None)
- if result is None:
- result = zip( ruleNames, range(0, len(ruleNames)))
- self.ruleIndexMapCache[ruleNames] = result
- return result
- def getTokenType(self, tokenName:str):
- ttype = self.getTokenTypeMap().get(tokenName, None)
- if ttype is not None:
- return ttype
- else:
- return Token.INVALID_TYPE
- # What is the error header, normally line/character position information?#
- def getErrorHeader(self, e:RecognitionException):
- line = e.getOffendingToken().line
- column = e.getOffendingToken().column
- return "line "+line+":"+column
- # How should a token be displayed in an error message? The default
- # is to display just the text, but during development you might
- # want to have a lot of information spit out. Override in that case
- # to use t.toString() (which, for CommonToken, dumps everything about
- # the token). This is better than forcing you to override a method in
- # your token objects because you don't have to go modify your lexer
- # so that it creates a new Java type.
- #
- # @deprecated This method is not called by the ANTLR 4 Runtime. Specific
- # implementations of {@link ANTLRErrorStrategy} may provide a similar
- # feature when necessary. For example, see
- # {@link DefaultErrorStrategy#getTokenErrorDisplay}.
- #
- def getTokenErrorDisplay(self, t:Token):
- if t is None:
- return "<no token>"
- s = t.text
- if s is None:
- if t.type==Token.EOF:
- s = "<EOF>"
- else:
- s = "<" + str(t.type) + ">"
- s = s.replace("\n","\\n")
- s = s.replace("\r","\\r")
- s = s.replace("\t","\\t")
- return "'" + s + "'"
- def getErrorListenerDispatch(self):
- return ProxyErrorListener(self._listeners)
- # subclass needs to override these if there are sempreds or actions
- # that the ATN interp needs to execute
- def sempred(self, localctx:RuleContext, ruleIndex:int, actionIndex:int):
- return True
- def precpred(self, localctx:RuleContext , precedence:int):
- return True
- @property
- def state(self):
- return self._stateNumber
- # Indicate that the recognizer has changed internal state that is
- # consistent with the ATN state passed in. This way we always know
- # where we are in the ATN as the parser goes along. The rule
- # context objects form a stack that lets us see the stack of
- # invoking rules. Combine this and we have complete ATN
- # configuration information.
- @state.setter
- def state(self, atnState:int):
- self._stateNumber = atnState
- del RecognitionException
|