Contrast how it is done now:
[-R [-H | -L | -P]] [-fi | -n] [-apvX] SRC... DST
and( optional(and('-R', or('-H', '-L', '-P'))), optional(or( '-fi', '-n' ) ), optional('-apvX'), repeatable('SRC'), 'DST')
Contrast how it is done now:
With a parser combinator based approach: And this didn't even handle the fact that options order is not important.