7

我想写一个类似 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多次指定参数,这是不正确的,因为您应该最多使用一次。

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

4

2 回答 2

4

您可以尝试以下方法:

(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 命令,我会感到惊讶。

于 2010-04-08T12:16:53.763 回答
-1

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

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

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

于 2010-04-09T14:43:15.860 回答