-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
problem combining partially overlapping parsers with Alternative #333
Comments
optparse has semantics more equivalent to Parsec compared to Attoparsec, in that branch selection doesn't backtrack on branch failure (Parsec has a primitive What's happened with "./foo a" is:
There are a few good reasons for this, but I think the clearest is to consider something like this: foo = (,) <$> flag' "FLAG" (short 'this') <*> strArgument (mempty) <* flag' () (short 'that')
<|> (,) <$> strOption (short 'this') <*> pure "what?" If we supported the backtracking you're alluding to: Even worse would be if we reversed the order of these choices foo = (,) <$> strOption (short 'this') <*> pure "what?"
<|> (,) <$> flag' "This" (short 'this') <*> strArgument (mempty) <* flag' () (short 'that') Here, In essence, permitting full backtracking or parallel branch evaluation means some terms can be absorbed both as positionals and option arguments, or flags and options. It would be downright confusing. Hopefully that's been persuasive. I'm happy to help with any interface design if you can point me to a code example. PS. loved your posts on your fridge! That's a great little project. |
Is that answer satisfactory @joeyh? If you have other ideas around how to deal with these issues I'm open, but I think it's important to not accidentally permit challenging parsers like those listed above. |
I just ran into this with data ModelOutputOpts
= OutputSamples FilePath
| OutputPlot FilePath
| OutputBoth FilePath FilePath
modelOutputParser :: Parser ModelOutputOpts
modelOutputParser
= OutputBoth <$> sampleOptionHelp <*> plotOptionHelp
<|> OutputSamples <$> sampleOption
<|> OutputPlot <$> plotOption
where
sampleSpec = long "output-samples" <> short 'o' <> metavar "FILEPATH"
sampleOption = strOption sampleSpec
sampleOptionHelp = strOption (sampleSpec <> help "Save samples from the distribution to FILEPATH")
plotSpec = long "output-plot" <> short 'p' <> metavar "FILEPATH"
plotOption = strOption plotSpec
plotOptionHelp = strOption (plotSpec <> help "Plot the resulting distribution to FILEPATH") @HuwCampbell I get that we can't have backtracking on by default, but you mention that Parsec has |
Despite being a bit awkward the PRs welcome. I'll have a look as well, but to be honest, I'm not convinced it's a great idea. |
The test program below prints this --help
Usage: foo ([--bar ARG] [string] | [string])
And "./foo --bar a b" works. However:
joey@darkstar:~>./foo a
Missing: --bar ARG
Seems that in bar <|> foo, the bar parser can fail in a way that makes it never try the
foo parser, which would succeed if it were tried.
If it's changed to foo <|> bar, the example above works, as does "./foo --bar a b" , so that version of the program works ok. Except, "./foo b --bar a" does not work; normally the bar
parser would accept that, but now the foo parser fails in a way that makes the bar parser not work.
The text was updated successfully, but these errors were encountered: