A loose grammar for a bluescript file: General notes: -- any char including '\n', but excluding the virtual char 'EOF' is rendered "unspecial" by the '\' escape. As a consequence, '\\' is required to represent the character '\'. Anywhere a range of characters that is defined as a negated set, (e.g. "anything except 'x'") can be assumed to accept an escaped character unless explicitly stated otherwise. -- literals are defined here either between single quotes (e.g. 'xyz' means the actual characters xyz) or as a range (e.g. [a-f] means 'a' or 'b' or 'c' or 'd' or 'e' or 'f') -- negated ranges are also used (e.g. [^a-f] would meaning anything except 'a' 'b' 'c' 'd' 'e' or 'f' -- * == repeated 0 or more times -- + == repeated 1 or more times -- () == grouping operators -- | == choice operator -- '\n' == the newline character, [^\n] == anything but the newline -- EOF == the virtal 'EOF' character script ::= ( comment | blank | command )* comment ::= space* '#' [^\n]* ('\n' | EOF) blank ::= space* ('\n' | EOF) command ::= (space* elem)+ space* elem ::= constant | string | variable | list | evallist string ::= '"' [^"]* '"' var ::= '$' varname | '${' [^}]* '}' varname ::= [a-zA-Z_][a-zA-Z0-9_]* list ::= '{' (space* elem)* space* '}' evallist ::= '[' command ']' constant ::= [^${["][^]* space := ' ' | '\t' | '\r' | '\n'