如何正确形式化 GNU/Linux 命令的命令行用法?

发布于 2024-08-28 02:47:55 字数 623 浏览 8 评论 0原文

我想写一个类似 BNF 的形式语法来描述一些 GNU/Linux 工具的命令行用法。例如,我可以将 cat 命令的用法描述为:

(cat-command) : 'cat' (arguments-list)
(arguments-list) : (argument)
(arguments-list) : (arguments-list) (argument)
(argument) : (file)

问题是我无法写下某些命令(例如 md5sum)的精确语法。我的第一次尝试如下:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (argument)
(arguments-list) : (arguments-list) (argument)
(argument) : (file)
(argument) : '--check'

但是正如您所看到的,此语法允许您根据需要多次指定 --check 参数,这是不正确的,因为您最多应该使用它一度。

我该如何解决这个问题?另外,我应该学习什么样的形式语法才能更好地处理这类问题?

I'd like to write down a BNF-like formal grammar for describing the command line usage of some GNU/Linux tools. For example I can describe the usage of the cat command as:

(cat-command) : 'cat' (arguments-list)
(arguments-list) : (argument)
(arguments-list) : (arguments-list) (argument)
(argument) : (file)

The problem is I can't write down a precise grammar for some commands such as md5sum. My first attempt at that would be the following:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (argument)
(arguments-list) : (arguments-list) (argument)
(argument) : (file)
(argument) : '--check'

But as you can see this grammar allows you to specify the --check argument as many times as you wish, which is incorrect as you should use it at most one time.

How can I fix that? Also, what kind of formal grammars I should study for better treating this kind of problems?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只是在用心讲痛 2024-09-04 02:47:55

您可以尝试类似的操作:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (file-arguments) | '--check' (file-arguments)
(file-arguments) : (file) (file-arguments)

假设您希望能够为每个命令指定一个 --check,但不依赖于它作为第一个参数,您可以使用:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (file-arguments) | (file-arguments) '--check' (file-arguments)
(file-arguments) : (file) (file-arguments)

另请注意,管道 ( |) 符号只是附加规则的快捷方式。以下是等效的:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (file-arguments) 
(arguments-list) : (file-arguments) '--check' (file-arguments)
(file-arguments) : (file) (file-arguments)

如果您不能使用上下文无关语法(如 BNF 中表达的语法)指定大多数 UNIX 命令,我会感到惊讶。

You could try something like:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (file-arguments) | '--check' (file-arguments)
(file-arguments) : (file) (file-arguments)

Assuming you want to be able to specify exactly one --check per command, but not depend on it being the first argument, you could use:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (file-arguments) | (file-arguments) '--check' (file-arguments)
(file-arguments) : (file) (file-arguments)

Also note, that the pipe (|) symbol is just a shortcut for an additional rule. The following is equivalent:

(md5sum-command) : 'md5sum' (arguments-list)
(arguments-list) : (file-arguments) 
(arguments-list) : (file-arguments) '--check' (file-arguments)
(file-arguments) : (file) (file-arguments)

I'd be surprised if you couldn't specify most unix commands with a context free grammar like those expressed in BNFs.

那些过往 2024-09-04 02:47:55

我可能找到了答案,尽管这不是预期的答案。您可以选择识别命令的正确性,而不是生成正确的命令。使用某种混合语言,您可以编写以下一组要求:

argument(0) == "md5sum"
forall i, if i != 0 then argument(i) == "--binary" or
                         argument(i) == "--text" or
                         argument(i) == "--check" or
                         argument(i) == "--status" or
                         argument(i) belongs to <file>
0 <= instances("--binary") + instances("--text") <= 1
0 <= instances("--check") <= 1
if instances("--check") == 1 then 0 <= instances("--status") <= 1

我不会将此答案标记为正确的答案,因为我仍然很好奇是否存在一种生成正确命令的方法。

I probably found an answer, although it's not the expected one. You can choose to recognise the correctness of a command instead of generate correct commands. Using some hybrid language, you can write the following set of requirements:

argument(0) == "md5sum"
forall i, if i != 0 then argument(i) == "--binary" or
                         argument(i) == "--text" or
                         argument(i) == "--check" or
                         argument(i) == "--status" or
                         argument(i) belongs to <file>
0 <= instances("--binary") + instances("--text") <= 1
0 <= instances("--check") <= 1
if instances("--check") == 1 then 0 <= instances("--status") <= 1

I won't mark this answer as the correct one because I'm still curious to know if there exists a way to generate correct commands.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文