class ParsleyCompatibleParser(object): def __init__(self, grammar, receiver, bindings): self._grammar = grammar self._receiver = receiver self._bindings = bindings self._bindings['receiver'] = receiver self.compiler = Compiler(self._grammar) self._rules = {} self._setup() def getParseTree(self, name): # XXX this must also cache .compileRule, not just .getRule # but apparently some state is still held inside the parse tree? if name not in self._rules: self._rules[name] = self.compiler.compileRule( self.compiler.getRule(name)) return self._rules[name] def _setup(self): parseTree = self.getParseTree(self._receiver.currentRule) self._interp = Interp(parseTree, self._setup, names=self._bindings) def receive(self, data): self._interp.receive(data)
class ParsleyCompatibleParser(object): def __init__(self, grammar, receiver, bindings): self._grammar = grammar self._receiver = receiver self._bindings = bindings self._bindings['receiver'] = receiver self.compiler = Compiler(self._grammar) self._rules = {} self._setup() def getParseTree(self, name): # XXX this must also cache .compileRule, not just .getRule # but apparently some state is still held inside the parse tree? if name not in self._rules: self._rules[name] = self.compiler.compileRule(self.compiler.getRule(name)) return self._rules[name] def _setup(self): parseTree = self.getParseTree(self._receiver.currentRule) self._interp = Interp(parseTree, self._setup, names=self._bindings) def receive(self, data): self._interp.receive(data)
def test_anyLength(self): source = "a = (digit*:y anything:x)" parseTree = getParseTree(source) i = Interp(parseTree, None) i.receive('12a') self.assertEqual(i.names['y'], ['1', '2']) self.assertEqual(i.names['x'], 'a')
def test_manyOr(self): source = """ a = (digit* 'x'):a | (digit* 'y'):a """ parseTree = getParseTree(source) i = Interp(parseTree, None) i.receive('12y') self.assertEqual(i.names['a'], 'y')
def test_nameOr(self): source = """ a = ('a' | 'b'):x """ parseTree = getParseTree(source) i = Interp(parseTree, None) i.receive('b') self.assertEqual(i.names['x'], 'b')
def test_name(self): source = """ a = anything{1}:x """ parseTree = getParseTree(source) i = Interp(parseTree, None) i.receive('a') self.assertEqual(i.names['x'], 'a')
def test_actionAnd(self): source = """ a = <anything '5'>:i -> int(i) """ parseTree = getParseTree(source) i = Interp(parseTree, None) result = i.receive('15') self.assertEqual(i.rv, 15)
def test_actionOr(self): source = """ a = ('0' | '5'):i -> int(i) """ parseTree = getParseTree(source) i = Interp(parseTree, None) result = i.receive('5') self.assertEqual(i.rv, 5)
def test_orAnd(self): source = """ a = ('b' | 'c') 'x' """ parseTree = getParseTree(source) i = Interp(parseTree, None) result = i.receive('cx') self.assertEqual(i.rv, 'x')
def test_consumedBy_double(self): source = """ nonzeroDigit = digit:x ?(x != '0') digits = <'0' | digit*>:x ':' <'0' | digit*>:y -> int(x) - int(y) """ parseTree = getParseTree(source, name='digits') i = Interp(parseTree, None) i.receive('12:34:') self.assertEqual(i.rv, 12 - 34)
def test_netstrings(self): source = """ nonzeroDigit = digit:x ?(x != '0') digits = <'0' | '1' '2' 'bar' | nonzeroDigit digit*>:i -> int(i) netstring = digits:length ':' <anything{length}>:string ',' -> string """ parseTree = getParseTree(source, name='netstring') i = Interp(parseTree, None) i.receive('3:asd,') self.assertEqual(i.rv, 'asd')
def test_callAfterOr(self): source = """ foo = ('b' | 'a') 'b' receiveNetstring = foo:string -> cb(string) """ _calls = [] def cb(i): _calls.append(i) parseTree = getParseTree(source, name='receiveNetstring') i = Interp(parseTree, None) i.names['cb'] = cb i.receive('ab') self.assertEqual(_calls, ['b'])
def test_actionOnce(self): """ The action is only called once, not more """ source = """ a = '0':i -> call(i) """ _calls = [] def cb(i): _calls.append(i) parseTree = getParseTree(source) i = Interp(parseTree, None) i.names['call'] = cb result = i.receive('0') self.assertEqual(_calls, ['0'])
def test_consumedBy(self): source = """ nonzeroDigit = digit:x ?(x != '0') digits = <'0' | digit*>:i """ parseTree = getParseTree(source) i = Interp(parseTree, None) i.receive('12:') self.assertEqual(i.names['i'], '12') i = Interp(parseTree, None) i.receive('0') self.assertEqual(i.names['i'], '0')
def test_reuseMany(self): receiver = NetstringsReceiver() compiler = Compiler(""" a = 'a'*:string 'b' -> receiver.netstringReceived(string) """) rule = compiler.getRule('a') parseTree = compiler.compileRule(rule) interp = Interp(parseTree, names={'receiver': receiver}) interp.receive('aab') assert receiver.strings == [['a', 'a']] interp = Interp(parseTree, names={'receiver': receiver}) interp.receive('aaab') assert receiver.strings == [['a', 'a'], ['a', 'a', 'a']]
def test_reuseParseTree_newInterp(self): receiver = NetstringsReceiver() compiler = Compiler(netstringsGrammar) rule = compiler.getRule('receiveNetstring') parseTree = compiler.compileRule(rule) interp = Interp(parseTree, names={'receiver': receiver}) interp.receive('11:aaaaaaaaaaa,') assert receiver.strings == ['aaaaaaaaaaa'] interp = Interp(parseTree, names={'receiver': receiver}) interp.receive('2:bb,') assert receiver.strings == ['aaaaaaaaaaa', 'bb']
def _setup(self): parseTree = self.getParseTree(self._receiver.currentRule) self._interp = Interp(parseTree, self._setup, names=self._bindings)