Parsing haskell-解析命令行和REPL命令及选项
我正在编写一个既有命令行界面又有交互模式的程序。在CLI模式下,它执行一个命令,打印结果并退出。在交互模式下,它使用GNU readline重复读取命令,执行它们并打印结果(以REPL的精神) 命令及其参数的语法几乎相同,无论它们是来自命令行还是frmo stdin。我希望通过使用单个框架来解析命令行和交互模式输入,最大限度地提高代码重用 我建议的语法如下(方括号表示可选部分,大括号重复):Parsing haskell-解析命令行和REPL命令及选项,parsing,haskell,command-line,Parsing,Haskell,Command Line,我正在编写一个既有命令行界面又有交互模式的程序。在CLI模式下,它执行一个命令,打印结果并退出。在交互模式下,它使用GNU readline重复读取命令,执行它们并打印结果(以REPL的精神) 命令及其参数的语法几乎相同,无论它们是来自命令行还是frmo stdin。我希望通过使用单个框架来解析命令行和交互模式输入,最大限度地提高代码重用 我建议的语法如下(方括号表示可选部分,大括号重复): 来自壳牌: program-name {[GLOBAL OPTION] ...} <comman
- 来自壳牌:
program-name {[GLOBAL OPTION] ...} <command> [{<command arg>|<GLOBAL OPTION>|<LOCAL OPTION> ...}]
程序名{[GLOBAL OPTION]…}[{| |…}]
- 在交互模式下:
<command> [{<command arg>|<GLOBAL OPTION>|<LOCAL OPTION> ...}]
如何为CL和REPL接口通用的命令和选项创建基本解析器,然后使用新命令和选项扩展基本解析器?
如何防止这些库在输入错误或使用“-help”时退出我的程序?
我计划为我的程序添加完整的i18n支持。因此,我想阻止我选择的库打印任何消息,因为所有消息都需要翻译。如何做到这一点
所以我希望你能给我一些提示,告诉我从这里该怎么走。cmdlib或OPTPASE应用程序(或其他库)是否支持我所寻找的内容?或者我应该恢复到手工制作的解析器吗?我想您可以使用我的库来实现这一点。子命令功能与您要查找的命令标志解析行为完全匹配 在两个不相交的选项集之间共享子命令会有点棘手,但是助手类型类应该能够做到这一点。粗略示例代码:
-- A type for options shared between CLI and interactive modes.
data CommonOptions = CommonOptions
{ optSomeOption :: Bool
}
instance Options CommonOptions where ...
-- A type for options only available in CLI mode (such as --version or --config-file)
data CliOptions = CliOptions
{ common :: CommonOptions
, version :: Bool
, configFile :: String
}
instance Options CliOptions where ...
-- if a command takes only global options, it can use this subcommand option type.
data NoOptions = NoOptions
instance Options NoOptions where
defineOptions = pure NoOptions
-- typeclass to let commands available in both modes access common options
class HasCommonOptions a where
getCommonOptions :: a -> CommonOptions
instance HasCommonOptions CommonOptions where
getCommonOptions = id
instance HasCommonOptions CliOptions where
getCommonOptions = common
commonCommands :: HasCommonOptions a => [Subcommand a (IO ())]
commonCommands = [... {- your commands here -} ...]
cliCommands :: HasCommonOptions a => [Subcommand a (IO ())]
cliCommands = commonCommands ++ [cmdRepl]
interactiveCommands :: HasCommonOptions a => [Subcommand a (IO ())]
interactiveCommands = commonCommands ++ [cmdQuit]
cmdRepl :: HasCommonOptions a => Subcommand a (IO ())
cmdRepl = subcommand "repl" $ \opts NoOptions -> do
{- run your interactive REPL here -}
cmdQuit :: Subcommand a (IO ())
cmdQuit = subcommand "quit" (\_ NoOptions -> exitSuccess)
我怀疑像runSubcommand
这样的助手函数不够专业化,因此在从REPL提示符拆分输入字符串后,您需要使用parseSubcommand
调用解析器。这些文档提供了如何检查已解析选项的示例,包括检查用户是否请求帮助
选项解析器本身不会打印任何输出,但可能很难国际化默认类型解析器生成的错误消息。请告诉我是否有任何对库的更改会有所帮助。base中有一个非常简单的命令行解析工具:。如果将选项作为列表提供给,则可以有3个列表:一个用于通用命令,一个用于REPL,一个用于CL
GetOpts
不会崩溃,它会返回错误消息,我认为任何好的库都应该这样做。它也不做任何打印,因为打印与命令行解析无关。在这里查看: