from yeanpypa import * non_zero_number = AnyOf('123456789') + ZeroOrMore(digit) rest_of_line = OneOrMore(NoneOf('\n')) plan = Literal('1..') + non_zero_number todo_directive = Optional(' ') + rest_of_line skip_reason = ZeroOrMore(NoneOf(' ')) + Literal(' ') + rest_of_line skip_directive = Optional(' ') + Literal('# ') + Literal('skip') + Optional(skip_reason) directive = Optional(' ') + Literal('# ') + (skip_directive | todo_directive) description = Optional(' ') + Optional('- ') + ZeroOrMore(NoneOf('#\n')) ok_not_ok = Literal('ok') | Literal('not ok') test_num = Optional(' ') + non_zero_number test = ok_not_ok + Optional(test_num) + Optional(description) + Optional(directive) plan_skipped = Literal('1..0') + skip_directive plan_first_tap = plan + ZeroOrMore(Literal('\n') + test) plan_last_tap = test + ZeroOrMore(Literal('\n') + test) + Optional(Literal('\n') + plan) tap = plan_skipped | plan_first_tap | plan_last_tap
I guess it works, but it feels like writing a regular expression longhand. I would probably also make it more lax if I wrote it as an re, as it would be easier to write
\s*-\s* in the
description rule, say.