def test_loop(self): self.assert_graphs( build( Loop([Sequence([n(1), n(2)])], state=DummyState(), lazy=True, label='x')), """digraph { 0 [label="x"] 1 [label="Match"] 2 [label="1"] 3 [label="2"] 4 [label="!"] 0 -> 1 0 -> 2 2 -> 3 3 -> 4 4 -> 0 }""") self.assert_graphs( build( Loop([Sequence([n(1), n(2)])], state=DummyState(), lazy=False, label='x')), """digraph { 0 [label="x"] 1 [label="1"] 2 [label="Match"] 3 [label="2"] 4 [label="!"] 0 -> 1 0 -> 2 1 -> 3 3 -> 4 4 -> 0 }""")
def _build_group(self): if self.__start: group = Sequence() group.append(self.__start) group.append(self.to_sequence()) group.append(EndGroup(self.__start.number)) self._parent._sequence.append(group) else: self._parent._sequence.append(self.to_sequence()) return self._parent
def test_sequence(self): self.assert_graphs( build(Sequence([n(1), n(2), n(3)])), """digraph { 0 [label="1"] 1 [label="2"] 2 [label="3"] 3 [label="Match"] 0 -> 1 1 -> 2 2 -> 3 }""")
def test_alternatives(self): self.assert_graphs( build(Alternatives()), """digraph { 0 [label="NoMatch"] 1 [label="Match"] 0 -> 1 }""") self.assert_graphs( build(Alternatives([Sequence([n(1), n(2), n(3)])])), """digraph { 0 [label="1"] 1 [label="2"] 2 [label="3"] 3 [label="Match"] 0 -> 1 1 -> 2 2 -> 3 }""") self.assert_graphs( build( Alternatives([ Sequence([n(1), n(2), n(3)]), Sequence([n(4), n(5)]), Sequence() ])), """digraph { 0 [label="...|..."] 1 [label="1"] 2 [label="4"] 3 [label="Match"] 4 [label="5"] 5 [label="2"] 6 [label="3"] 0 -> 1 0 -> 2 0 -> 3 2 -> 4 4 -> 3 1 -> 5 5 -> 6 6 -> 3 }""")
def group_reference(self, next, number, state): try: text = state.groups.group(number) if text is None: return (None, []) elif text: alphabet = self._parser_state.alphabet graph = Sequence([String(alphabet.join(c)) for c in text]) graph = graph.join(next[0], self._parser_state) return (None, [state.clone(graph=graph)]) else: return (None, [state.advance()]) except KeyError: return (None, [])
def callback(self, yesno, terminal): # first callback - have 'yes', possibly terminated by '|' if self.__yes is None: (self.__yes, yesno) = (yesno, None) # collect second alternative if terminal == '|': return YesNoBuilder(self, self._state, self.__parent, ')') # final callback - build yes and no (if present) yes = self.__yes.to_sequence() no = yesno.to_sequence() if yesno else Sequence() label = ('...' if yes else '') + ('|...' if no else '') if not label: label = '|' split = lambda label: Conditional(self.__name, label) alternatives = Alternatives([no, yes], label=label, split=split) self.__parent._sequence.append(alternatives) return self.__parent
def __init__(self, state): super(ReplacementBuilder, self).__init__(state) self._sequence = Sequence()
def __init__(self, state): super(SequenceBuilder, self).__init__(state) self._alternatives = Alternatives() self._sequence = Sequence()
def to_sequence(self): if not self._alternatives: return self._sequence else: self.__start_new_alternative() return Sequence([self._alternatives])
def __start_new_alternative(self): self._alternatives.append(self._sequence) self._sequence = Sequence()