4 ms·
I don't get it either. Normally you'd use coroutines to have an implicit state machine, without writing out explicit states.
by eternauta3k 7y ago
I don't get it either. Normally you'd use coroutines to have an implicit state machine, without writing out explicit states.
- glxxyz 7y agoYes the regex-parsing FSM class in the article looks cleaner with a single coroutine: class FSM: def __init__(self): self.match = False self.current_state = self.create_state_machine() next(self.current_state) def does_match(self): return self.match def send(self, char): try: self.current_state.send(char) except StopIteration: self.match = False pass def create_state_machine(self): char = yield if char == 'a': while True: char = yield if char == 'b': pass elif char == 'c': self.match = True yield break else: break
- OJFord 7y agoThat makes more sense. And we could still break out states into functions without being quite so explicit as in the article (and without the __init__ problem I described): def create_state_machine(self): if yield == 'a': yield from self.q2() def q2(self): while (char := yield) == 'b': pass if char == 'c': self.match = True Or something like that anyway, untested of course. (NB that actually fixes a bug in yours in that it would continue processing 'b's after the 'c' - of course that's still a match for the regex, but the FSM should have stopped.)
- glxxyz 7y agoThanks for pointing that out, I think I fixed it. Not well tested ;) I'm not sure if the way that you're using yield within the if and while statements works correctly. I like the idea of replacing state transitions with method calls but you'll run into recursion depth problems with a state machine that alternates between two states.
- OJFord 7y ago> I'm not sure if the way that you're using yield within the if and while statements works correctly. You're right... Perhaps I'm not so surprised that `if yield == val:` is a SyntaxError, but that `yield` can't be used as an rvalue to a walrus operator (that the `while` example essentially boils down to) surprises me: >>> char = yield File "<stdin>", line 1 SyntaxError: 'yield' outside function >>> >>> # i.e. OK, that's the error we want if it works >>> >>> got_b = (char := yield) == 'b' File "<stdin>", line 1 got_b = (char := yield) == 'b' ^ SyntaxError: invalid syntax