How to formalize GNU / Linux command line usage?

I would like to write a formal grammar similar to BNF to describe the use of the command line by some GNU / Linux tools. For example, I can describe the use of the cat as:

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

The problem is that I cannot write the exact grammar for some commands, such as md5sum . My first attempt is as follows:

 (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 --check many times as you want, which is incorrect since you should use it no more than once.

How can i fix this? Also, what formal grammars should I study to better treat such problems?

+7
grammar bnf
source share
2 answers

You can try something like:

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

Assuming that you want to specify exactly one --check for each command, but not depend on the fact that this is the first argument, you can 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 ( | ) character is just a shortcut to 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 would be surprised if you could not specify most of the unix commands with contextual free grammar similar to those expressed in BNF.

+4
source share

I probably found the answer, although this is not expected. You can choose the correct command instead of generating the correct command. 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 will not mark this answer as correct, because I am still interested to find out if there is a way to generate the correct commands.

-one
source share

All Articles