InputStream.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. #
  7. # Vacuum all input from a string and then treat it like a buffer.
  8. #
  9. from antlr4.Token import Token
  10. class InputStream (object):
  11. __slots__ = ('name', 'strdata', '_index', 'data', '_size')
  12. def __init__(self, data: str):
  13. self.name = "<empty>"
  14. self.strdata = data
  15. self._loadString()
  16. def _loadString(self):
  17. self._index = 0
  18. self.data = [ord(c) for c in self.strdata]
  19. self._size = len(self.data)
  20. @property
  21. def index(self):
  22. return self._index
  23. @property
  24. def size(self):
  25. return self._size
  26. # Reset the stream so that it's in the same state it was
  27. # when the object was created *except* the data array is not
  28. # touched.
  29. #
  30. def reset(self):
  31. self._index = 0
  32. def consume(self):
  33. if self._index >= self._size:
  34. assert self.LA(1) == Token.EOF
  35. raise Exception("cannot consume EOF")
  36. self._index += 1
  37. def LA(self, offset: int):
  38. if offset==0:
  39. return 0 # undefined
  40. if offset<0:
  41. offset += 1 # e.g., translate LA(-1) to use offset=0
  42. pos = self._index + offset - 1
  43. if pos < 0 or pos >= self._size: # invalid
  44. return Token.EOF
  45. return self.data[pos]
  46. def LT(self, offset: int):
  47. return self.LA(offset)
  48. # mark/release do nothing; we have entire buffer
  49. def mark(self):
  50. return -1
  51. def release(self, marker: int):
  52. pass
  53. # consume() ahead until p==_index; can't just set p=_index as we must
  54. # update line and column. If we seek backwards, just set p
  55. #
  56. def seek(self, _index: int):
  57. if _index<=self._index:
  58. self._index = _index # just jump; don't update stream state (line, ...)
  59. return
  60. # seek forward
  61. self._index = min(_index, self._size)
  62. def getText(self, start :int, stop: int):
  63. if stop >= self._size:
  64. stop = self._size-1
  65. if start >= self._size:
  66. return ""
  67. else:
  68. return self.strdata[start:stop+1]
  69. def __str__(self):
  70. return self.strdata