Assume we have a string s (a C char *
) that is a program in a language L. I want to parse L and know the following from the specification
The following characters must be quoted if they are to represent themselves:
| & ; < > ( ) $ ` \ " '
So let's say I scan and parse the string checking char by char and dynamically building up a structure in-memory for the whole program. The program can be as short as echo foobar
but the important is to parse the different meanings of |
in a string such as echo foo|cat
and echo 'foo|cat'
where the first is a pipeline and the second is printing a literal.
Now I have a new token char c that is the current char of s. Now I want to have a function boolean isBetweenQuotes(int position, string s)
that returns true iff the character at position position
is quoted in the string s
- do you agree this is a good way of solving the problem? What should the function isBetweenQuotes
look like? The return values should be for example
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 */
I was recommended that a could use a finite state machine and/or an abstract syntax tree and do the code either with flex/bison or a custom scanner/tokenizer. I can currently execute trivial pipelines and I'm trying to make the shell code more readable than other current shells. I've studied the source for the following shells: ash, dash, sash, posh and custom shells and the most readable code has been sash, while I understand that posh and dash are more posix compliant.
My goal is to make a shell that can perform infinite pipeline by recursion with fork
and exec
and solve some signal handling problem that other shells might have if they allocate memory with malloc
.