Why write an FSM and backtracking explicitly? Use parser combinators, they basically do the same thing, just express it in a clearer, grammar-friendly way: http://theorangeduck.com/page/you-could-have-invented-parser...
Contrast how it is done now:
[-R [-H | -L | -P]] [-fi | -n] [-apvX] SRC... DST
With a parser combinator based approach: and(
optional(and('-R', or('-H', '-L', '-P'))),
optional(or(
'-fi',
'-n'
)
),
optional('-apvX'),
repeatable('SRC'),
'DST')
And this didn't even handle the fact that options order is not important.