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