有很多众所周知的命令行参数解析器,比如argp或C ++的boost :: program_options的子集。
例如,我最近尝试编写一个让我用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) {
...
}
}
但很快发现解析位置无关的标志并不简单(例如-fgx
将与-f -xg
相同),然后在混合中抛出具有值args的位置无关标志变得非常简单(例如tar -xvzf frob.tar.gz
)。
只有经验主义这些问题才变得明显;我没有为此搜索找到任何例子。
你对这个话题有什么好的资源吗?你自己的最佳实践是什么?
注意:即使我在命名一些C ++示例,但这个问题应该与语言无关。我要求算法和一般性建议。
答案 0 :(得分:0)
我认为如果你在编写命令行解析器而没有声明部分(如示例中所示),并且允许对flags / short-options进行分组(-xf
将与{{1}相同你必须以某种方式强制执行客户呼叫的排序。
考虑例如(假设它是对unix -x -f
程序的有效调用):
tar
这里有以下选项:
tar -vfxul.tar -x
如果您首先测试x
v
f=xul.tar
标志(p代码),
x
你在回答问题时遇到了麻烦:哪个state = parse(argc, argv)
x_set = flag (state, 'x')
...
filename = mandatory (state, 'f' or "filename")
?
x
因为解析器还不知道tar -vfxul.tar -x
^ ^
x? x?
选项,所以它可能会假设在filename
中,每个字符vfxul.tar
,v
,{{1} },...)可能是一个被识别的标志。
所以我认为你最好的猜测(不使用简单的人工智能或一些复杂的启发式)现在就是第一次出现x
。
我相信你应该在解析一个带有短选项的值后禁止解析任何flag-options:
u
这会迫使你进入一种必须将代码压缩到某个顺序的情况,这甚至会降低这种库的适用性,所以这只适用于非常简单的情况解析器,你有非相互依存的参数列表。
注意:您只需要对可能存在短选项或允许使用flag- / short-option分组的解析进行重新排序。