Parsing 编写命令行参数解析器 P>有很多众所周知的命令行参数分析器,如ARGP或Boosiv:PosithOpjyC++选项。 例如,我最近尝试编写一个让我解析C++中的简单场景: int main (int argc, char *argv[]) { auto state = parse (argc, argv); const auto foo = mandatory<int> (state, {'f', "foo"}); const auto bar = optional_with_default<int>(state, {'b', "bar"}, 42); const auto frob = optional<std::string> (state, {'F', "frob"}); if (!frob) { ... } } intmain(intargc,char*argv[]){ 自动状态=解析(argc,argv); const auto foo=强制(状态,{'f','foo}); const auto bar=带有默认值的可选_(状态,{'b',“bar”},42); const auto frob=可选(状态,{'F',“frob”}); 如果(!frob){ ... } }

Parsing 编写命令行参数解析器 P>有很多众所周知的命令行参数分析器,如ARGP或Boosiv:PosithOpjyC++选项。 例如,我最近尝试编写一个让我解析C++中的简单场景: int main (int argc, char *argv[]) { auto state = parse (argc, argv); const auto foo = mandatory<int> (state, {'f', "foo"}); const auto bar = optional_with_default<int>(state, {'b', "bar"}, 42); const auto frob = optional<std::string> (state, {'F', "frob"}); if (!frob) { ... } } intmain(intargc,char*argv[]){ 自动状态=解析(argc,argv); const auto foo=强制(状态,{'f','foo}); const auto bar=带有默认值的可选_(状态,{'b',“bar”},42); const auto frob=可选(状态,{'F',“frob”}); 如果(!frob){ ... } },parsing,language-agnostic,command-line-arguments,Parsing,Language Agnostic,Command Line Arguments,但是很快就发现解析位置独立的标志并不简单(例如,-fgx将与-f-xg相同),然后在混合中抛出带有值args的位置独立标志就变得非常简单(例如,tar-xvzf frob.tar.gz) 这些问题只因经验主义而变得明显;我没有找到任何东西,例如用于此搜索的内容 你知道这方面有什么好的资源吗?您自己的最佳实践是什么 注:即使我命名了一些C++例子,这个问题也应该是语言不可知的。我在征求算法和一般性建议。我认为如果您编写的命令行解析器没有声明性部分(如示例中所示),并且允许对标志/短选项进行分组(

但是很快就发现解析位置独立的标志并不简单(例如,
-fgx
将与
-f-xg
相同),然后在混合中抛出带有值args的位置独立标志就变得非常简单(例如,
tar-xvzf frob.tar.gz

这些问题只因经验主义而变得明显;我没有找到任何东西,例如用于此搜索的内容

你知道这方面有什么好的资源吗?您自己的最佳实践是什么



注:即使我命名了一些C++例子,这个问题也应该是语言不可知的。我在征求算法和一般性建议。

我认为如果您编写的命令行解析器没有声明性部分(如示例中所示),并且允许对标志/短选项进行分组(
-xf
-x-f
相同),那么您必须以某种方式强制执行客户端调用的顺序

例如(假设它是unix
tar
程序的有效调用):

这里有以下选项:

x
v
f=xul.tar
如果您首先测试
x
标志(p-code)

您在回答以下问题时遇到困难:哪个
x

tar -vfxul.tar -x
       ^        ^
       x?       x?
因为解析器还不知道
filename
选项,它可能会假设在
vfxul.tar
中,每个字符(
v
x
u
,…)都可能是要识别的标志

因此,我认为你现在最好的猜测(不必求助于简单的人工智能或一些复杂的启发式)就是第一次出现
x

我认为您应该禁止在解析了具有值的短选项之后解析任何标志选项:

state = parse(argc, argv)
x_set = flag (state, 'x')
...
filename = mandatory (state, 'f' or "filename") // THROW ERROR HERE!
这迫使您必须将代码压缩成特定的顺序,这进一步降低了此类库的适用性,因此这实际上只适用于具有非相互依赖参数列表的非常简单的情况

注意:您只需要在可能存在短选项或允许标记/短选项分组的情况下重新排列部件


来源
  • 积极主义

我认为,如果您编写的命令行解析器没有声明性部分(如示例中所示),并且允许对标志/短选项进行分组(
-xf
-x-f
相同),那么您必须以某种方式强制执行客户端调用的顺序

例如(假设它是unix
tar
程序的有效调用):

这里有以下选项:

x
v
f=xul.tar
如果您首先测试
x
标志(p-code)

您在回答以下问题时遇到困难:哪个
x

tar -vfxul.tar -x
       ^        ^
       x?       x?
因为解析器还不知道
filename
选项,它可能会假设在
vfxul.tar
中,每个字符(
v
x
u
,…)都可能是要识别的标志

因此,我认为你现在最好的猜测(不必求助于简单的人工智能或一些复杂的启发式)就是第一次出现
x

我认为您应该禁止在解析了具有值的短选项之后解析任何标志选项:

state = parse(argc, argv)
x_set = flag (state, 'x')
...
filename = mandatory (state, 'f' or "filename") // THROW ERROR HERE!
这迫使您必须将代码压缩成特定的顺序,这进一步降低了此类库的适用性,因此这实际上只适用于具有非相互依赖参数列表的非常简单的情况

注意:您只需要在可能存在短选项或允许标记/短选项分组的情况下重新排列部件


来源
  • 积极主义

我知道问题通常应涵盖具体问题。但是这一点对于自我研究来说确实很困难,所以请考虑常见问题解答中的一般问题,但是如果您的问题通常涉及……某个人评论的特定编程问题(当然很快就被删除了,所以我看不到)
Apache Commons CLI喜欢它。请注意自我搜索。
:我正在寻找有关构建此类解析器的信息,因为我发现现有的解析器很难使用。我不是在寻找解析器:)为什么需要混合使用选项声明和选项参数?我认为这会影响使用,造成很多死角。毕竟,tar-xvf文件有什么问题?@Rogach:看我的答案。您显示的示例已经将标志(x,v)与短选项(f)混合在一起。当
tar
允许
tar-xvffile
而没有空间时,痛苦就来了。解析标志可能意味着从文件名中删除字母。这正是我的意思-为什么需要没有空格的部分?只需将“-someletters”类型的每个构造视为一个单字母选项列表,不要将它们与参数混合。或者这在你的情况下是不可能的?我知道问题通常应该包括具体的问题。但是这一点对于自我研究来说确实很困难,所以请考虑常见问题解答中的一般问题,但是如果您的问题通常涉及……某个人评论的特定编程问题(当然很快就被删除了,所以我看不到)
Apache Commons CLI喜欢它。请注意自我搜索。
:我正在寻找有关构造此类解析器的信息,因为我找到了现有的o