diff options
author | 2011-07-27 16:55:46 +0800 | |
---|---|---|
committer | 2011-08-02 15:52:18 +0800 | |
commit | 9042ed3ac8b75202e71e5de49376e0b1c68e847f (patch) | |
tree | 611e5275680a3dd5f61e920d546b72631c6ebc52 | |
parent | Parser: improve exported variable handling (diff) | |
download | libbash-9042ed3ac8b75202e71e5de49376e0b1c68e847f.tar.gz libbash-9042ed3ac8b75202e71e5de49376e0b1c68e847f.tar.bz2 libbash-9042ed3ac8b75202e71e5de49376e0b1c68e847f.zip |
Parser: support empty command with redirection
Now only '>' is supported because there would be a lot of conflicts if
we want to fully support this. Also the operator other than '>' doesn't
make sense.
-rw-r--r-- | bashast/bashast.g | 34 | ||||
-rw-r--r-- | bashast/libbashWalker.g | 6 | ||||
-rw-r--r-- | scripts/command_execution.bash | 1 | ||||
-rwxr-xr-x | test/verify_error_output_test.sh | 2 |
4 files changed, 31 insertions, 12 deletions
diff --git a/bashast/bashast.g b/bashast/bashast.g index 55a499d..dc0ff1b 100644 --- a/bashast/bashast.g +++ b/bashast/bashast.g @@ -226,6 +226,9 @@ tokens{ ||token == LESS_THAN ||token == GREATER_THAN ||token == RSHIFT + ||token == AMP_LESS_THAN + ||token == AMP_GREATER_THAN + ||token == AMP_RSHIFT // for end of command ||token == SEMIC ||token == EOL @@ -325,7 +328,7 @@ here_document_operator here_document_begin : ( - token=~(EOL|BLANK|LESS_THAN|HERE_STRING_OP|AMP|GREATER_THAN|RSHIFT) + token=~(EOL|BLANK|LESS_THAN|HERE_STRING_OP|GREATER_THAN|RSHIFT|AMP_LESS_THAN|AMP_GREATER_THAN|AMP_RSHIFT) { if(LA(-1) != DQUOTE && LA(-1) != ESC) { @@ -347,13 +350,13 @@ redirection_operator : BLANK! DIGIT redirection_operator | BLANK? ( - AMP LESS_THAN -> OP["&<"] + AMP_LESS_THAN -> OP["&<"] | GREATER_THAN AMP -> OP[">&"] | LESS_THAN AMP -> OP["<&"] | LESS_THAN GREATER_THAN -> OP["<>"] | RSHIFT -> OP[">>"] - | AMP GREATER_THAN -> OP["&>"] - | AMP RSHIFT -> OP ["&>>"] + | AMP_GREATER_THAN -> OP["&>"] + | AMP_RSHIFT -> OP ["&>>"] | LESS_THAN -> LESS_THAN | GREATER_THAN -> GREATER_THAN ); @@ -376,21 +379,29 @@ command_atom | -> ^(VARIABLE_DEFINITIONS variable_definitions) ) | (EXPORT) => EXPORT BLANK export_item -> ^(STRING EXPORT) ^(STRING ^(DOUBLE_QUOTED_STRING export_item)) - | string_expr_no_reserved_word + | command_name ( (BLANK? parens) => BLANK? parens wspace? compound_command - -> ^(FUNCTION["function"] string_expr_no_reserved_word compound_command) + -> ^(FUNCTION["function"] command_name compound_command) | ( {LA(1) == BLANK && ( !is_special_token(LA(2)) // redirection - &&(LA(2) != DIGIT || (LA(3) != AMP && LA(3) != LESS_THAN - && LA(3) != GREATER_THAN && LA(3) != RSHIFT)) + &&(LA(2) != DIGIT || (LA(3) != AMP_LESS_THAN && + LA(3) != AMP_GREATER_THAN && + LA(3) != AMP_RSHIFT && + LA(3) != GREATER_THAN && + LA(3) != LESS_THAN && + LA(3) != RSHIFT)) )}? => BLANK bash_command_arguments - )* -> string_expr_no_reserved_word bash_command_arguments* + )* -> command_name bash_command_arguments* ); +command_name + : string_expr_no_reserved_word + | {LA(1) == GREATER_THAN}? => redirection_atom -> ^(STRING NAME) redirection_atom; + variable_definitions : ( variable_definition_atom ((BLANK name (LSQUARE|EQUALS|PLUS EQUALS)) => BLANK! variable_definition_atom)* @@ -765,7 +776,7 @@ pattern_char : LETTER|DIGIT|OTHER|QMARK|COLON|AT|SEMIC|POUND|SLASH |BANG|TIMES|COMMA|PIPE|AMP|MINUS|PLUS|PCT|LSQUARE|RSQUARE |RPAREN|LPAREN|RBRACE|LBRACE|DOLLAR|TICK|DOT|LESS_THAN - |GREATER_THAN|SQUOTE|DQUOTE; + |GREATER_THAN|SQUOTE|DQUOTE|AMP_LESS_THAN|AMP_GREATER_THAN|AMP_RSHIFT; variable_reference : DOLLAR LBRACE parameter_expansion RBRACE -> ^(VAR_REF parameter_expansion) @@ -1041,6 +1052,9 @@ LESS_THAN : '<'; GREATER_THAN : '>'; LSHIFT : '<<'; RSHIFT : '>>'; +AMP_LESS_THAN : '&<'; +AMP_GREATER_THAN : '&>'; +AMP_RSHIFT : '&>>'; SEMIC : ';'; DOUBLE_SEMIC : ';;'; diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g index d1bbe93..7deb461 100644 --- a/bashast/libbashWalker.g +++ b/bashast/libbashWalker.g @@ -579,7 +579,7 @@ simple_command } :string_expr (argument[libbash_args])* execute_command[$string_expr.libbash_value, libbash_args]; -execute_command[const std::string& name, std::vector<std::string>& libbash_args] +execute_command[std::string& name, std::vector<std::string>& libbash_args] @declarations { interpreter::local_scope current_scope(*walker); std::unique_ptr<std::ostream> out; @@ -588,6 +588,10 @@ execute_command[const std::string& name, std::vector<std::string>& libbash_args] bool redirection = false; } :var_def[true]* (redirect[out, err, in]{ redirection = true; })* { + // Empty command, still need to run bash redirection + if(name.empty()) + name = ":"; + if(walker->has_function(name)) { if(redirection) diff --git a/scripts/command_execution.bash b/scripts/command_execution.bash index 05e2177..132d72d 100644 --- a/scripts/command_execution.bash +++ b/scripts/command_execution.bash @@ -74,3 +74,4 @@ o Hello\ world echo \`\(\)\$\>\<\` export SRC_URI="${SRC_URI} http://www.oracle.com/technology/products/berkeley-db/db/update/${MY_PV}/patch.${MY_PV}.${i}" +> /dev/null diff --git a/test/verify_error_output_test.sh b/test/verify_error_output_test.sh index 48e972b..cbf6cf2 100755 --- a/test/verify_error_output_test.sh +++ b/test/verify_error_output_test.sh @@ -2,4 +2,4 @@ illegal="${srcdir}/scripts/illegal_script.sh" output=$(./variable_printer "$illegal" 2>&1) -[[ $output == "${illegal}(1) : error 10 : Missing token, at offset 3"* ]] +[[ $output == "${illegal}(1) : error 1 : Unexpected token, at offset 3"* ]] |