Supponiamo di avere una stringa s (un C char *
) che è un programma in una lingua L. Voglio analizzare L e sapere quanto segue da specification
The following characters must be quoted if they are to represent themselves:
| & ; < > ( ) $ ' \ " '
Quindi diciamo che analizzo e analizzo la stringa controllando char per char e costruendo dinamicamente una struttura in memoria per l'intero programma. Il programma può essere corto come echo foobar
ma l'importante è analizzare i diversi significati di |
in una stringa come echo foo|cat
e echo 'foo|cat'
dove il primo è una pipeline e il secondo sta stampando un valore letterale.
Ora ho un nuovo token char c che è il carattere corrente di s. Ora voglio avere una funzione boolean isBetweenQuotes(int position, string s)
che restituisce true se il carattere alla posizione position
è quotato nella stringa s
- sei d'accordo che questo è un buon modo per risolvere il problema? Come dovrebbe essere la funzione isBetweenQuotes
? I valori di ritorno dovrebbero essere ad esempio
isBetweenQuotes(6, "echo foobar"); /* returns false */
isBetweenQuotes(6, "echo foobar|less"); /* returns false */
isBetweenQuotes(6, "echo 'foobar'|less"); /* returns true */
isBetweenQuotes(20, "echo "foo bar"|awk '{print $1}''"); /* returns true */
Mi è stato suggerito che si potesse usare una macchina a stati finiti e / o un albero di sintassi astratto e fare il codice con flex / bison o con uno scanner / tokenizzatore personalizzato. Attualmente posso eseguire pipeline banali e sto cercando di rendere il codice shell più leggibile rispetto alle altre shell attuali. Ho studiato il codice sorgente per le seguenti shell: ash, dash, sash, posh e shell personalizzate e il codice più leggibile è stato sash, mentre capisco che posh e dash sono più conformi a posix.
Il mio obiettivo è creare una shell in grado di eseguire pipeline infinite mediante ricorsione con fork
e exec
e risolvere alcuni problemi di gestione dei segnali che potrebbero avere altre shell se allocano memoria con malloc
.