30
30
raise TypeError("Characters are not iterable")
32
class IterBuffer(object):
32
class InputStream(object):
34
Wrapper for an iterable that allows pushing items onto it. The basic input
35
mechanism used by OMeta grammars.
34
The basic input mechanism used by OMeta grammars.
38
def __init__(self, iterable):
37
def fromIterable(cls, iterable):
40
39
@param iterable: Any iterable Python object.
42
self.original = iterable
43
41
if isinstance(iterable, str):
44
self.iterable = (character(c) for c in iterable)
42
data = [character(c) for c in iterable]
45
43
elif isinstance(iterable, unicode):
46
self.iterable = (unicodeCharacter(c) for c in iterable)
44
data = [unicodeCharacter(c) for c in iterable]
48
self.iterable = iter(iterable)
51
self.markPositions = []
48
fromIterable = classmethod(fromIterable)
50
def __init__(self, data, position):
52
self.position = position
57
def getMemo(self, name):
59
Returns the memo record for the named rule.
60
@param name: A rule name.
62
m = self.memo.get(self.position, None)
64
return m.get(name, None)
67
def setMemo(self, pos, name, rec):
69
Store a memo record for the given value and position for the given
71
@param pos: A position in the input.
72
@param name: A rule name.
73
@param rec: A memo record.
75
self.memo.setdefault(pos, {})[name] = rec
85
Fetch the next item in the stream.
91
val = self.buffer.pop()
93
val = self.iterable.next()
94
for buf in self.markBuffers:
56
if self.position >= len(self.data):
57
raise IndexError("out of range")
58
return self.data[self.position]
61
return InputStream(self.data, self.position+1)
103
Rewind by a single item.
105
self.buffer.append(self.lastThing)
106
for buf in self.markBuffers:
114
Push an object onto the stream, such that it will be returned on the
118
self.args.append(obj)
119
if self.position in self.memo:
120
self.memo[self.position] = {}
124
Mark a position in the stream.
126
self.markPositions.append(self.position)
127
self.markBuffers.append([])
128
return len(self.markBuffers)-1
131
def unmark(self, mark):
133
Register disinterest in returning to a previously marked stream
136
del self.markBuffers[mark:]
137
del self.markPositions[mark:]
140
def rewind(self, mark):
142
Return to a previously marked position in the stream.
144
saved = self.markBuffers[mark][::-1]
145
self.buffer.extend(saved)
146
self.position = self.markPositions[mark]
149
for buf in self.markBuffers:
150
del buf[-len(saved):]
153
def seekForwardTo(self, position):
155
Advance until the input reaches the requested position.
157
while position > self.position:
64
return InputStream(self.data, self.position-1)
66
def getMemo(self, name):
68
Returns the memo record for the named rule.
69
@param name: A rule name.
71
return self.memo.get(name, None)
74
def setMemo(self, name, rec):
76
Store a memo record for the given value and position for the given
78
@param name: A rule name.
79
@param rec: A memo record.
84
class ArgInput(object):
85
def __init__(self, arg, parent):
97
def getMemo(self, name):
99
Returns the memo record for the named rule.
100
@param name: A rule name.
102
return self.memo.get(name, None)
105
def setMemo(self, name, rec):
107
Store a memo record for the given value and position for the given
109
@param name: A rule name.
110
@param rec: A memo record.
112
self.memo[name] = rec
160
116
class LeftRecursion(object):
222
179
if rule.func_code.co_argcount - 1 != len(args):
223
180
for arg in args[::-1]:
181
self.input = ArgInput(arg, self.input)
227
184
return rule(*args)
228
185
memoRec = self.input.getMemo(ruleName)
229
186
if memoRec is None:
230
m = self.input.mark()
231
oldPosition = self.input.position
187
oldPosition = self.input
232
188
lr = LeftRecursion()
233
memoRec = self.input.setMemo(self.input.position, ruleName, lr)
189
memoRec = self.input.setMemo(ruleName, lr)
235
memoRec = self.input.setMemo(self.input.position, ruleName,
236
[rule(), self.input.position])
191
memoRec = self.input.setMemo(ruleName,
192
[rule(), self.input])
238
sentinel = self.input.position
194
sentinel = self.input
242
m = self.input.mark()
197
self.input = oldPosition
244
if (self.input.position == sentinel):
199
if (self.input == sentinel):
247
memoRec = self.input.setMemo(oldPosition, ruleName,
248
[ans, self.input.position])
202
memoRec = oldPosition.setMemo(ruleName,
250
204
except ParseError:
206
self.input = oldPosition
254
208
elif isinstance(memoRec, LeftRecursion):
255
209
memoRec.detected = True
256
210
raise ParseError()
257
self.input.seekForwardTo(memoRec[1])
211
self.input = memoRec[1]
258
212
return memoRec[0]