diff options
author | 2011-07-27 19:06:53 +0800 | |
---|---|---|
committer | 2011-08-02 15:52:18 +0800 | |
commit | 2afd34d4fef6dbdfb9afa2a371303dcf2fa4ab6e (patch) | |
tree | 0d80d50146d1eaca9d56b229e584703026f8798d /bashast | |
parent | Parser: support empty command with redirection (diff) | |
download | libbash-2afd34d4fef6dbdfb9afa2a371303dcf2fa4ab6e.tar.gz libbash-2afd34d4fef6dbdfb9afa2a371303dcf2fa4ab6e.tar.bz2 libbash-2afd34d4fef6dbdfb9afa2a371303dcf2fa4ab6e.zip |
Builtin: reimplement the local built-in
Now the local built-in is not handled only in parser grammar so that
expansions can happen for the arguments. '=' is not checked in the local
and export built-in anymore because we do not generate empty AST for
"export foo".
Diffstat (limited to 'bashast')
-rw-r--r-- | bashast/bashast.g | 39 | ||||
-rw-r--r-- | bashast/gunit/array.gunit | 2 | ||||
-rw-r--r-- | bashast/gunit/simp_command.gunit | 2 | ||||
-rw-r--r-- | bashast/libbashWalker.g | 6 |
4 files changed, 27 insertions, 22 deletions
diff --git a/bashast/bashast.g b/bashast/bashast.g index dc0ff1b..cb0a63d 100644 --- a/bashast/bashast.g +++ b/bashast/bashast.g @@ -373,12 +373,15 @@ command_atom : (FOR|SELECT|IF|WHILE|UNTIL|CASE|LPAREN|LBRACE|LLPAREN|LSQUARE|TEST_EXPR) => compound_command | FUNCTION BLANK string_expr_no_reserved_word ((BLANK? parens wspace?)|wspace) compound_command -> ^(FUNCTION string_expr_no_reserved_word compound_command) - | (name (LSQUARE|EQUALS|PLUS EQUALS)|LOCAL) => variable_definitions + | (name (LSQUARE|EQUALS|PLUS EQUALS)) => variable_definitions ( (BLANK bash_command) => BLANK bash_command -> bash_command variable_definitions | -> ^(VARIABLE_DEFINITIONS variable_definitions) ) - | (EXPORT) => EXPORT BLANK export_item -> ^(STRING EXPORT) ^(STRING ^(DOUBLE_QUOTED_STRING export_item)) + | (EXPORT) => EXPORT BLANK builtin_variable_definition_item + -> ^(STRING EXPORT) ^(STRING ^(DOUBLE_QUOTED_STRING builtin_variable_definition_item)) + | (LOCAL) => LOCAL BLANK builtin_variable_definition_item + -> ^(STRING LOCAL) ^(STRING ^(DOUBLE_QUOTED_STRING builtin_variable_definition_item)) | command_name ( (BLANK? parens) => BLANK? parens wspace? compound_command @@ -403,10 +406,7 @@ command_name | {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)* - | (LOCAL) => LOCAL BLANK! local_item ((BLANK name) => BLANK! local_item)* - ); + : variable_definition_atom ((BLANK name (LSQUARE|EQUALS|PLUS EQUALS)) => BLANK! variable_definition_atom)* ; variable_definition_atom : name LSQUARE BLANK? explicit_arithmetic BLANK? RSQUARE EQUALS string_expr? @@ -445,26 +445,26 @@ array_atom | ); -local_item - : variable_definition_atom - | name -> ^(EQUALS name) - | MINUS op=LETTER { -#ifdef OUTPUT_C - std::string option = get_string(op); - if(option != "i" && option != "a") - throw libbash::unsupported_exception("We do not support -" + option + " for local"); -#endif - } ->; -export_item +builtin_variable_definition_item : ((~EOL) => expansion_base)+; +#ifdef OUTPUT_C +builtin_variable_definitions[bool local] + : {$local}? => (builtin_variable_definition_atom) (BLANK builtin_variable_definition_atom)* + -> ^(LIST ^(COMMAND ^(VARIABLE_DEFINITIONS LOCAL builtin_variable_definition_atom+))) + | {!$local}? => (builtin_variable_definition_atom) (BLANK builtin_variable_definition_atom)* + -> ^(LIST ^(COMMAND ^(VARIABLE_DEFINITIONS builtin_variable_definition_atom+))); +#else builtin_variable_definitions : (builtin_variable_definition_atom) (BLANK builtin_variable_definition_atom)* - -> ^(LIST ^(COMMAND ^(VARIABLE_DEFINITIONS builtin_variable_definition_atom +))); + -> ^(LIST ^(COMMAND ^(VARIABLE_DEFINITIONS builtin_variable_definition_atom+))); +#endif builtin_variable_definition_atom : variable_definition_atom - | name ->; + // We completely ignore the options for export, local and readonly for now + | (MINUS LETTER BLANK) => MINUS LETTER -> + | name -> ^(EQUALS name ^(STRING ^(VAR_REF name))); bash_command : string_expr_no_reserved_word ((BLANK bash_command_arguments) => BLANK! bash_command_arguments)*; @@ -702,6 +702,7 @@ expansion_base | (ESC DQUOTE) => ESC DQUOTE -> DQUOTE | (ESC TICK) => ESC TICK -> TICK | (ESC DOLLAR) => ESC DOLLAR -> DOLLAR + | (brace_expansion) => brace_expansion | .; all_expansions diff --git a/bashast/gunit/array.gunit b/bashast/gunit/array.gunit index fe49511..514eb53 100644 --- a/bashast/gunit/array.gunit +++ b/bashast/gunit/array.gunit @@ -32,7 +32,7 @@ variable_definition_atom: "asdf+=(a)" -> (PLUS_ASSIGN asdf (ARRAY (STRING a))) builtin_variable_definitions: -"asdf=(a b c d) ade acd=bde" -> (LIST (COMMAND (VARIABLE_DEFINITIONS (= asdf (ARRAY (STRING a) (STRING b) (STRING c) (STRING d))) (= acd (STRING bde))))) +"asdf=(a b c d) ade acd=bde" -> (LIST (COMMAND (VARIABLE_DEFINITIONS (= asdf (ARRAY (STRING a) (STRING b) (STRING c) (STRING d))) (EQUALS ade (STRING (VAR_REF ade))) (= acd (STRING bde))))) variable_reference: "$asdf" -> (VAR_REF asdf) diff --git a/bashast/gunit/simp_command.gunit b/bashast/gunit/simp_command.gunit index fdd4346..2d98061 100644 --- a/bashast/gunit/simp_command.gunit +++ b/bashast/gunit/simp_command.gunit @@ -27,7 +27,7 @@ command_atom: "./foobär" -> (STRING . / foob ä r) "cat ~/Documents/todo.txt" -> (STRING cat) (STRING ~ / Documents / todo . txt) "dodir ${foo}/${bar}" -> (STRING dodir) (STRING (VAR_REF foo) / (VAR_REF bar)) -"local a=123 b=(1 2 3) c" -> (VARIABLE_DEFINITIONS local (= a (STRING 123)) (= b (ARRAY (STRING 1) (STRING 2) (STRING 3))) (EQUALS c)) +"local a=123 b=(1 2 3) c" -> (STRING local) (STRING (DOUBLE_QUOTED_STRING a = 123 b = ( 1 2 3 ) c)) "echo {}{}}{{{}}{{}" -> (STRING echo) (STRING { } { } } { { { } } { { }) "echo \"ab#af ###\" #abc" -> (STRING echo) (STRING (DOUBLE_QUOTED_STRING ab # af # # #)) diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g index 7deb461..65fade5 100644 --- a/bashast/libbashWalker.g +++ b/bashast/libbashWalker.g @@ -581,12 +581,16 @@ simple_command execute_command[std::string& name, std::vector<std::string>& libbash_args] @declarations { - interpreter::local_scope current_scope(*walker); + std::unique_ptr<interpreter::local_scope> current_scope; std::unique_ptr<std::ostream> out; std::unique_ptr<std::ostream> err; std::unique_ptr<std::istream> in; bool redirection = false; } +@init { + if(name != "local") + current_scope.reset(new interpreter::local_scope(*walker)); +} :var_def[true]* (redirect[out, err, in]{ redirection = true; })* { // Empty command, still need to run bash redirection if(name.empty()) |