modelli per convertire l'input da riga di comando dell'utente in comandi del computer

3

Il problema: 50 diversi comandi che vengono digitati in una riga di comando per un programma, diciamo per dire a un robot cosa fare. Alcuni dei comandi hanno valori determinati dall'utente come travel north 5 (5 unità di tipo predeterminato). Altri sono semplici comandi, scan area , che non hanno input definiti dall'utente.

Nei miei corsi, ho semplicemente creato una catena di

if(userInput == "command"){do something}
else if(userInput == "anotherCommand"){do something else}
else if else if else if

fino a quando tutte le condizioni non si sono incontrate, che sono sempre state poche. Per i comandi su cui sto lavorando ora, sto solo analizzando la prima parola da usare nel condizionale e poi usando le altre parole se necessario.

Ho provato a cercare informazioni su questo argomento, ma continuo a ricevere informazioni su come leggere l'input dell'utente e non sul modo migliore di ordinare attraverso una grande quantità di possibili input dell'utente.

È solo la natura della lettura in input dell'utente che l'unica soluzione è solo avere una catena di dichiarazioni if else fino a quando tutti gli input sono coperti?

    
posta WP0987 18.08.2016 - 05:04
fonte

3 risposte

2

Quello che stai descrivendo è un modo perfettamente ragionevole, anche se ad-hoc, di analizzare i comandi.

In alternativa puoi definire una grammatica e analizzare formalmente l'input.

E ci sono anche in mezzo.

Ad esempio, puoi impostare una macchina a stati semplice per elaborare la prima parola del comando carattere per carattere per determinare l'azione da eseguire. Una tale macchina a stati potrebbe ospitare contemporaneamente la ricerca di tutte le parole (comando iniziale).

Ad esempio, supponiamo che tu stia cercando "viaggio" o "svolta". Si imposta una macchina a stati in cui nello stato 0, "t" porta allo stato 1, e tutti gli altri portano a, diciamo, lo stato -1 (errore). Dallo stato 1, 'r' conduce allo stato 2, e 'u' conduce allo stato 3. Da stato 2, il resto di 'avel' seguito da un separatore è accettato, carattere per carattere e stato per stato, come comando "viaggio ", e dallo stato 3, il resto di" urn "seguito da un separatore è accettato come comando" turn "(e tutto il resto si traduce in errore).

Una tale macchina di stato eviterebbe i confronti ripetitivi delle stringhe e la sequenza estesa if-then-elseif-elseif-elseif, che insieme rendono le prestazioni migliori per le parole precedenti nella sequenza e peggio per le parole successive nella sequenza .

    
risposta data 18.08.2016 - 06:22
fonte
2

Ci sono probabilmente modi migliori per gestirlo rispetto all'utilizzo di un enorme blocco if-else (come l'astrazione di comandi e l'analisi degli argomenti in una o più classi), ma essenzialmente si farebbe lo stesso genere di cose: capire il comando basato sul primo token e invocazione della "azione" associata per analizzare il resto dell'input per gli argomenti desiderati, convertirli ai tipi desiderati e scrivere la logica per effettuare effettivamente tali modifiche.

In alternativa, se hai il controllo sul formato di input e in base alla lingua, puoi semplicemente scrivere i "comandi" di input in un vero linguaggio di programmazione e inviarlo a un interprete. Ad esempio, se stai scrivendo in JS, potresti fare qualcosa del tipo:

var robot = Robot();
var travel = function(dir, units) {
    robot.move(...);
    // ...
};

//...

var cmd = "travel('north', 5)";
eval(cmd);

Questo è probabilmente eccessivo e molto più di lavoro rispetto a tutto ciò che l'analisi manuale, dal momento che dovresti capire come esporre il codice che effettivamente fa il lavoro (nell'esempio sopra, la funzione travel ) a qualsiasi script lingua che decidi di usare (la lingua che interpreta l'interprete) e per caricare correttamente quel contesto nell'interprete. Ci sono alcuni linguaggi che rendono questo più facile di altri, perché hanno un metodo di eval() incorporato (o simile) che può eseguire pezzi arbitrari di codice nella stessa lingua e con il contesto esistente che il metodo eval è in (vale a dire qualunque cosa sia nello scope sarà definita).

Python è un'altra lingua che può farlo.

    
risposta data 18.08.2016 - 06:21
fonte
1

Ci sono librerie che possono aiutarti con questo genere di cose, ma non è terribilmente difficile creare le tue astrazioni. Un modello comune è qualcosa come:

registerCommand("travel (north|south|east|west) (\d+)", travelCommand)
registerCommand("scan area", scanAreaCommand)

def travelCommand(args: Array[String]) = ???
def scanAreaCommand(args: Array[String]) = ???

Quindi devi solo scorrere i comandi registrati fino a trovare quello che corrisponde alla regex, estrarre le corrispondenze e passarle al callback registrato.

È possibile diventare più sofisticati e creare una grammatica e un albero di analisi dai comandi registrati per fare cose come il completamento della tabulazione e la convalida del tipo, che alcune di quelle citate librerie fanno, ma il ciclo delle regex è sufficiente per molti progetti.

    
risposta data 18.08.2016 - 07:23
fonte

Leggi altre domande sui tag