Skip to content

Commit faf8cea

Browse files
committed
Make ParserProtocol use TrampolinedParser.
1 parent ff0468f commit faf8cea

File tree

2 files changed

+20
-55
lines changed

2 files changed

+20
-55
lines changed

ometa/protocol.py

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,34 @@
11
from twisted.internet.protocol import Protocol
22
from twisted.python.failure import Failure
33

4-
from ometa.interp import TrampolinedGrammarInterpreter, _feed_me
4+
from ometa.tube import TrampolinedParser
55

6-
class ParserProtocol(Protocol):
7-
currentRule = 'initial'
86

7+
class ParserProtocol(Protocol):
98
def __init__(self, grammar, senderFactory, receiverFactory, bindings):
109
self.grammar = grammar
1110
self.bindings = dict(bindings)
1211
self.senderFactory = senderFactory
1312
self.receiverFactory = receiverFactory
1413
self.disconnecting = False
1514

16-
def setNextRule(self, rule):
17-
self.currentRule = rule
18-
1915
def connectionMade(self):
2016
self.sender = self.senderFactory(self.transport)
21-
self.bindings['receiver'] = self.receiver = self.receiverFactory(
22-
self.sender, self)
17+
self.receiver = self.receiverFactory(self.sender)
2318
self.receiver.prepareParsing()
24-
self._setupInterp()
25-
26-
def _setupInterp(self):
27-
self._interp = TrampolinedGrammarInterpreter(
28-
self.grammar, self.currentRule, callback=self._parsedRule,
29-
globals=self.bindings)
30-
31-
def _parsedRule(self, nextRule, position):
32-
if nextRule is not None:
33-
self.currentRule = nextRule
19+
self.parser = TrampolinedParser(
20+
self.grammar, self.receiver, self.bindings)
3421

3522
def dataReceived(self, data):
3623
if self.disconnecting:
3724
return
3825

39-
while data:
40-
try:
41-
status = self._interp.receive(data)
42-
except Exception:
43-
self.connectionLost(Failure())
44-
self.transport.abortConnection()
45-
return
46-
else:
47-
if status is _feed_me:
48-
return
49-
data = ''.join(self._interp.input.data[self._interp.input.position:])
50-
self._setupInterp()
26+
try:
27+
self.parser.receive(data)
28+
except Exception:
29+
self.connectionLost(Failure())
30+
self.transport.abortConnection()
31+
return
5132

5233
def connectionLost(self, reason):
5334
if self.disconnecting:

ometa/test/test_protocol.py

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class SomeException(Exception):
3434

3535

3636
class ReceiverFactory(object):
37-
def __init__(self, sender, parser):
37+
currentRule = 'initial'
38+
39+
def __init__(self, sender):
3840
self.sender = sender
39-
self.parser = parser
4041
self.calls = []
4142
self.returnMap = {}
4243
self.connected = False
@@ -47,7 +48,8 @@ def prepareParsing(self):
4748

4849
def __call__(self, v):
4950
self.calls.append(v)
50-
return self.returnMap.get(v)
51+
if v in self.returnMap:
52+
self.currentRule = self.returnMap[v]
5153

5254
def raiseSomething(self):
5355
raise SomeException()
@@ -77,12 +79,6 @@ def test_transportPassed(self):
7779
self.protocol.makeConnection(transport)
7880
self.assertEqual(transport, self.protocol.sender.transport)
7981

80-
def test_parserPassed(self):
81-
"""The protocol is passed to the receiver."""
82-
transport = object()
83-
self.protocol.makeConnection(transport)
84-
self.assertEqual(self.protocol, self.protocol.receiver.parser)
85-
8682
def test_senderPassed(self):
8783
"""The sender is passed to the receiver."""
8884
self.protocol.makeConnection(None)
@@ -133,29 +129,17 @@ def test_ruleSwitchingWithChunks(self):
133129
self.protocol.dataReceived('baa')
134130
self.assertEqual(self.protocol.receiver.calls, ['a', 'b', 'a'])
135131

136-
def test_ruleSwitchingViaReceiver(self):
132+
def test_rulesCannotBeSwitchedDuringParsing(self):
137133
"""
138-
The receiver is able to set the the next rule to be parsed with the
139-
parser passed to it.
134+
One can set a new rule during parsing, but it won't change the rule
135+
currently being parsed.
140136
"""
141137
self.protocol.makeConnection(None)
142138
self.protocol.dataReceived('aa')
143139
self.assertEqual(self.protocol.receiver.calls, ['a'])
144140
self.protocol.dataReceived('a')
145141
self.assertEqual(self.protocol.receiver.calls, ['a'])
146-
self.protocol.receiver.parser.setNextRule('someB')
147-
self.protocol.dataReceived('abb')
148-
self.assertEqual(self.protocol.receiver.calls, ['a', 'a', 'b'])
149-
150-
def test_ruleSwitchingViaReceiverGetsOverridden(self):
151-
"""Returning a new rule takes priority over calling setNextRule."""
152-
self.protocol.makeConnection(None)
153-
self.protocol.dataReceived('aa')
154-
self.assertEqual(self.protocol.receiver.calls, ['a'])
155-
self.protocol.dataReceived('a')
156-
self.assertEqual(self.protocol.receiver.calls, ['a'])
157-
self.protocol.receiver.parser.setNextRule('someB')
158-
self.protocol.receiver.returnMap['a'] = 'someC'
142+
self.protocol.receiver.currentRule = 'someC'
159143
self.protocol.dataReceived('acc')
160144
self.assertEqual(self.protocol.receiver.calls, ['a', 'a', 'c'])
161145

0 commit comments

Comments
 (0)