2010-04-08 9 views
7

Vorrei scrivere una grammatica formale simile a BNF per descrivere l'utilizzo da riga di comando di alcuni strumenti GNU/Linux. Per esempio posso descrivere l'uso del comando cat come:Come formalizzare correttamente l'uso della riga di comando dei comandi GNU/Linux?

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

Il problema è che non posso scrivere una grammatica preciso per alcuni comandi come md5sum. Il mio primo tentativo di questo sarebbe il seguente:

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

Ma come si può vedere questa grammatica consente di specificare l'argomento --check tutte le volte che lo si desidera, che non è corretto, come si dovrebbe usare al massimo una sola volta .

Come posso risolvere il problema? Inoltre, che tipo di grammatiche formali dovrei studiare per trattare meglio questo tipo di problemi?

+1

Sei sicuro che la tua grammatica non sia corretta? Per me molti comandi Unix accettano tranquillamente più occorrenze dello stesso argomento, ad esempio 'ls -l -l -l'. –

+0

Sì, hai ragione. Ma forse ci sono alcuni strumenti che non consentono ripetizioni. Potrei anche scrivere il mio programma che non consente le ripetizioni. Quindi penso che il mio problema sia ancora rilevante. –

risposta

4

Si potrebbe provare qualcosa di simile:

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

Supponendo che si vuole essere in grado di specificare esattamente un --check al comando, ma non dipendere da esso essere il primo argomento, è possibile utilizzare:

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

Si noti inoltre che il simbolo pipe (|) è solo una scorciatoia per una regola aggiuntiva. Quello che segue è equivalente:

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

Sarei sorpreso se non è possibile specificare più comandi UNIX con una grammatica libera contesto come quelli espressi in BNFS.

+0

La tua versione sembra funzionare, ma non è abbastanza generale. Ad esempio, non è necessario inserire l'argomento '--check' subito dopo l'argomento 'md5sum': è possibile avere molti file specificati prima e dopo di esso. –

+0

Dopo aver letto la tua nuova versione, sono riuscito a scrivere quanto segue: (elenco-argomenti): [(elenco-file)] [(modo-opzione)] [(elenco-file)] ['--check'] [(file-list)] (argomenti-lista): [(elenco-file)] ['--check'] [(elenco-file)] [(modo-opzione)] [(elenco-file)] (opzione-mode): '--binary' (opzione-mode): '--text' Non potrei abbreviare ulteriormente. Quindi aggiungere altri argomenti come "--quiet", "--warn" o "--status" risulterebbe in una grammatica eccessivamente lunga per un comando così semplice. –

+0

Vero. Probabilmente vuoi fare la differenza tra gli argomenti che sono solo flag (possono apparire ovunque nella lista degli argomenti, agire globalmente) e gli argomenti che agiscono sui file che seguono. –

-1

Probabilmente ho trovato una risposta, anche se non è quella prevista. È possibile scegliere di riconoscere la correttezza di un comando anziché generare comandi corretti. Usando un linguaggio ibrido, è possibile scrivere la seguente serie di requisiti:

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 

Non voglio segnare questa risposta come quella giusta, perché io sono ancora curioso di sapere se esiste un modo per generare corretta comandi.