ATNSimulator.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #
  2. # Copyright (c) 2012-2017 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. from antlr4.PredictionContext import PredictionContextCache, PredictionContext, getCachedPredictionContext
  7. from antlr4.atn.ATN import ATN
  8. from antlr4.atn.ATNConfigSet import ATNConfigSet
  9. from antlr4.dfa.DFAState import DFAState
  10. class ATNSimulator(object):
  11. __slots__ = ('atn', 'sharedContextCache', '__dict__')
  12. # Must distinguish between missing edge and edge we know leads nowhere#/
  13. ERROR = DFAState(configs=ATNConfigSet())
  14. ERROR.stateNumber = 0x7FFFFFFF
  15. # The context cache maps all PredictionContext objects that are ==
  16. # to a single cached copy. This cache is shared across all contexts
  17. # in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet
  18. # to use only cached nodes/graphs in addDFAState(). We don't want to
  19. # fill this during closure() since there are lots of contexts that
  20. # pop up but are not used ever again. It also greatly slows down closure().
  21. #
  22. # <p>This cache makes a huge difference in memory and a little bit in speed.
  23. # For the Java grammar on java.*, it dropped the memory requirements
  24. # at the end from 25M to 16M. We don't store any of the full context
  25. # graphs in the DFA because they are limited to local context only,
  26. # but apparently there's a lot of repetition there as well. We optimize
  27. # the config contexts before storing the config set in the DFA states
  28. # by literally rebuilding them with cached subgraphs only.</p>
  29. #
  30. # <p>I tried a cache for use during closure operations, that was
  31. # whacked after each adaptivePredict(). It cost a little bit
  32. # more time I think and doesn't save on the overall footprint
  33. # so it's not worth the complexity.</p>
  34. #/
  35. def __init__(self, atn:ATN, sharedContextCache:PredictionContextCache):
  36. self.atn = atn
  37. self.sharedContextCache = sharedContextCache
  38. def getCachedContext(self, context:PredictionContext):
  39. if self.sharedContextCache is None:
  40. return context
  41. visited = dict()
  42. return getCachedPredictionContext(context, self.sharedContextCache, visited)