def test_stringConsumedBy(self): called = [] grammarSource = "rule = <'x'+>:y -> y" grammar = OMeta(grammarSource).parseGrammar("Parser") def interp(result, error): called.append(result) trampoline = TrampolinedGrammarInterpreter(grammar, "rule", interp) trampoline.receive("xxxxx") trampoline.end() self.assertEqual(called, ["xxxxx"])
def _setupInterp(self): """ Resets the parser. The parser will begin parsing with the rule named 'initial'. """ self._interp = TrampolinedGrammarInterpreter( grammar=self.grammar, ruleName=self.receiver.currentRule, callback=None, globals=self.bindings)
def _setupInterp(self): """ Resets the parser. The parser will begin parsing with the rule named 'initial'. """ self._interp = TrampolinedGrammarInterpreter( grammar=self.grammar, rule=self.receiver.currentRule, callback=None, globals=self.bindings)
def test_failure(self): g = OMeta(""" foo = 'a':one baz:two 'd'+ 'e' -> (one, two) baz = 'b' | 'c' """, {}) tree = g.parseGrammar('TestGrammar') i = TrampolinedGrammarInterpreter( tree, 'foo', callback=lambda x: setattr(self, 'result', x)) e = self.assertRaises(ParseError, i.receive, 'foobar') self.assertEqual(str(e), "\nfoobar\n^\nParse error at line 2, column 0:" " expected the character 'a'. trail: []\n")
class TrampolinedParser: _buffer = b'' """ A parser that incrementally parses incoming data. """ def __init__(self, grammar, receiver, bindings): """ Initializes the parser. @param grammar: The grammar used to parse the incoming data. @param receiver: Responsible for logic operation on the parsed data. Typically, the logic operation will be invoked inside the grammar, e.g., rule = expr1 expr2 (-> receiver.doSomeStuff()) @param bindings: The namespace that can be accessed inside the grammar. """ self.grammar = grammar self.bindings = dict(bindings) self.bindings['receiver'] = self.receiver = receiver self._setupInterp() def _setupInterp(self): """ Resets the parser. The parser will begin parsing with the rule named 'initial'. """ self._interp = TrampolinedGrammarInterpreter( grammar=self.grammar, rule=self.receiver.currentRule, callback=None, globals=self.bindings) def receive(self, data): """ Receive the incoming data and begin parsing. The parser will parse the data incrementally according to the 'initial' rule in the grammar. @param data: The raw data received. """ if self._buffer: data = self._buffer + data # Note here to reset the buffer self._buffer = b'' while data and not getattr(self.receiver, "paused", False): status = self._interp.receive(data) if status is _feed_me: return data = ''.join(self._interp.input.data[self._interp.input.position:]) self._setupInterp() if data: self._buffer = data
class ParserProtocol(Protocol): currentRule = 'initial' def __init__(self, grammar, senderFactory, receiverFactory, bindings): self.grammar = grammar self.bindings = dict(bindings) self.senderFactory = senderFactory self.receiverFactory = receiverFactory self.disconnecting = False def setNextRule(self, rule): self.currentRule = rule def connectionMade(self): self.sender = self.senderFactory(self.transport) self.bindings['receiver'] = self.receiver = self.receiverFactory( self.sender, self) self.receiver.connectionMade() self._setupInterp() def _setupInterp(self): self._interp = TrampolinedGrammarInterpreter( self.grammar, self.currentRule, callback=self._parsedRule, globals=self.bindings) def _parsedRule(self, nextRule, position): if nextRule is not None: self.currentRule = nextRule def dataReceived(self, data): if self.disconnecting: return while data: try: status = self._interp.receive(data) except Exception: self.connectionLost(Failure()) self.transport.abortConnection() return else: if status is _feed_me: return data = ''.join(self._interp.input.data[self._interp.input.position:]) self._setupInterp() def connectionLost(self, reason): if self.disconnecting: return self.receiver.connectionLost(reason) self.disconnecting = True
def doIt(s): """ @param s: The string to be parsed by the wrapped grammar. """ tree = not isinstance(s, basestring) if tree: raise unittest.SkipTest("Not applicable for push parsing") results = [] def whenDone(val, err): results.append(val) parser = TrampolinedGrammarInterpreter(self._tree, name, whenDone, self._globals) for i, c in enumerate(s): assert len(results) == 0 parser.receive(c) parser.end() if results and parser.input.position == len(parser.input.data): try: return ''.join(results[0]) except TypeError: return results[0] else: raise parser.currentError
class TrampolinedParser: """ A parser that incrementally parses incoming data. """ def __init__(self, grammar, receiver, bindings): """ Initializes the parser. @param grammar: The grammar used to parse the incoming data. @param receiver: Responsible for logic operation on the parsed data. Typically, the logic operation will be invoked inside the grammar, e.g., rule = expr1 expr2 (-> receiver.doSomeStuff()) @param bindings: The namespace that can be accessed inside the grammar. """ self.grammar = grammar self.bindings = dict(bindings) self.bindings['receiver'] = self.receiver = receiver self._setupInterp() def _setupInterp(self): """ Resets the parser. The parser will begin parsing with the rule named 'initial'. """ self._interp = TrampolinedGrammarInterpreter( grammar=self.grammar, ruleName=self.receiver.currentRule, callback=None, globals=self.bindings) def receive(self, data): """ Receive the incoming data and begin parsing. The parser will parse the data incrementally according to the 'initial' rule in the grammar. @param data: The raw data received. """ while data: status = self._interp.receive(data) if status is _feed_me: return data = ''.join( self._interp.input.data[self._interp.input.position:]) self._setupInterp()
def _setupInterp(self): self._interp = TrampolinedGrammarInterpreter( self.grammar, self.currentRule, callback=self._parsedRule, globals=self.bindings)