Как правильно формализовать использование командной строки команд GNU / Linux? - PullRequest
7 голосов
/ 08 апреля 2010

Я хотел бы записать 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 столько раз, сколько вы хотите, что неверно, так как вы должны его использоватьмаксимум один раз.

Как я могу это исправить?Кроме того, какие формальные грамматики я должен изучить для лучшего лечения такого рода проблем?

Ответы [ 2 ]

4 голосов
/ 08 апреля 2010

Вы можете попробовать что-то вроде:

(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)

Я был бы удивлен, если бы вы не могли указать большинство команд unix с контекстно-свободной грамматикой, подобной выраженной в BNF.

0 голосов
/ 09 апреля 2010

Я, наверное, нашел ответ, хотя это не ожидаемый ответ. Вы можете распознать правильность команды, а не генерировать правильные команды. Используя некоторый гибридный язык, вы можете написать следующий набор требований:

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

Я не буду отмечать этот ответ как правильный, потому что мне все еще интересно узнать, существует ли способ генерировать правильных команд.

...