编写命令行参数解析器

时间:2012-07-10 08:42:25

标签: parsing language-agnostic command-line-arguments

有很多众所周知的命令行参数解析器,比如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 ++示例,但这个问题应该与语言无关。我要求算法和一般性建议。

1 个答案:

答案 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.tarv,{{1} },...)可能是一个被识别的标志。

所以我认为你最好的猜测(不使用简单的人工智能或一些复杂的启发式)现在就是第一次出现x

我相信你应该在解析一个带有短选项的值后禁止解析任何flag-options:

u

这会迫使你进入一种必须将代码压缩到某个顺序的情况,这甚至会降低这种库的适用性,所以这只适用于非常简单的情况解析器,你有非相互依存的参数列表。

注意:您只需要对可能存在短选项或允许使用flag- / short-option分组的解析进行重新排序。


来源

  • Empricism