2010-04-08 16 views
7

Me gustaría escribir una gramática formal similar a BNF para describir el uso de la línea de comandos de algunas herramientas de GNU/Linux. Por ejemplo, yo puedo describir el uso del comando cat como:¿Cómo formalizar correctamente el uso de la línea de comandos de los comandos de GNU/Linux?

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

El problema es que no puedo escribir una gramática precisa para algunos comandos como md5sum. Mi primer intento en ese sería el siguiente:

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

Pero como se puede ver esta gramática permite especificar el argumento --check tantas veces como desee, lo cual es incorrecto, ya que se debe utilizar como máximo una hora .

¿Cómo puedo solucionar eso? Además, ¿qué tipo de gramáticas formales debería estudiar para tratar mejor este tipo de problemas?

+1

¿Estás seguro de que tu gramática es incorrecta? Para mí, muchos de los comandos de Unix aceptan muy felizmente múltiples ocurrencias del mismo argumento, por ejemplo, 'ls -l -l -l'. –

+0

Sí, tienes razón. Pero tal vez hay algunas herramientas que no permiten las repeticiones. También puedo escribir mi propio programa que no permite repeticiones. Entonces creo que mi problema aún es relevante. –

Respuesta

4

Usted podría intentar algo como:

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

Suponiendo que desea ser capaz de especificar exactamente un --check por comando, pero no depende de él que es el primer argumento, se puede utilizar:

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

También tenga en cuenta que el símbolo de la tubería (|) es solo un atajo para una regla adicional. El siguiente es equivalente:

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

Me sorprendería si no podría especificar mayoría de los comandos UNIX con una gramática libre de contexto como los expresados ​​en BNF.

+0

Su versión parece funcionar, pero no es lo suficientemente general. Por ejemplo, no es necesario que coloque el argumento '--check' inmediatamente después del argumento 'md5sum': puede tener muchos archivos especificados antes y después de él. –

+0

Después de leer su nueva versión, logré escribir lo siguiente: (arguments-list): [(files-list)] [(mode-option)] [(files-list)] ['--check'] [(lista de archivos)] (arguments-list): [(lista de archivos)] ['--check'] [(lista de archivos)] [(modo-opción)] [(lista de archivos)] (modo-opción): '--binary' (modo-opción): '--text' No podría abreviarlo más. Así que agregar otros argumentos como '--quiet', '--warn' o '--status' resultaría en una gramática excesivamente larga para un comando tan simple. –

+0

Es cierto. Probablemente desee marcar la diferencia entre los argumentos que son solo indicadores (pueden aparecer en cualquier lugar de la lista de argumentos, actuar globalmente) y los argumentos que actúan en los siguientes archivos. –

-1

Probablemente encontré una respuesta, aunque no es la esperada. Puede elegir reconocer la corrección de un comando en lugar de generar los comandos correctos. El uso de un lenguaje híbrido, se puede escribir la siguiente serie de requisitos:

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 

no voy a marcar esta respuesta como la correcta porque todavía estoy curioso por saber si existe una manera de generar correcta comandos.

Cuestiones relacionadas