diff options
author | Mu Qiao <qiaomuf@gentoo.org> | 2011-07-20 20:18:12 +0800 |
---|---|---|
committer | Mu Qiao <qiaomuf@gentoo.org> | 2011-07-20 23:15:43 +0800 |
commit | 1d9a50c973025c3c1e9d48f3b2e0a8b7baf41278 (patch) | |
tree | 409879b967abec1657b6f99d49d3ebad463c9ccd | |
parent | Parser: add rules to perform bash expansions (diff) | |
download | libbash-1d9a50c973025c3c1e9d48f3b2e0a8b7baf41278.tar.gz libbash-1d9a50c973025c3c1e9d48f3b2e0a8b7baf41278.tar.bz2 libbash-1d9a50c973025c3c1e9d48f3b2e0a8b7baf41278.zip |
Walker: reimplement runtime for parameter expansion
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | bashast/libbashWalker.g | 35 | ||||
-rw-r--r-- | src/core/bash_ast.cpp | 10 | ||||
-rw-r--r-- | src/core/bash_ast.h | 8 |
4 files changed, 42 insertions, 12 deletions
diff --git a/Makefile.am b/Makefile.am index 87d9c9a..92ecdfe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,7 @@ BASH_TESTS = scripts/var_def.bash \ scripts/command_execution.bash \ scripts/function_def.bash \ scripts/arithmetic_assignment.bash \ + scripts/var_expansion.bash \ scripts/binary_arithmetic.bash EBUILD_LOG_COMPILER = $(srcdir)/test/ebuild_compiler.sh diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g index 3462c96..4b0364e 100644 --- a/bashast/libbashWalker.g +++ b/bashast/libbashWalker.g @@ -450,19 +450,30 @@ array_name returns[std::string libbash_value] |TIMES { $libbash_value = "*"; } |AT { $libbash_value = "*"; }; +// Now the rule will call back to parser and perform the expansions +raw_string returns[std::string libbash_value] +@declarations { + std::string str; +} + :(^(STRING EMPTY_EXPANSION_VALUE)) => ^(STRING EMPTY_EXPANSION_VALUE) + |^(STRING (libbash_string=any_string { str += libbash_string; })+) { + bash_ast ast(std::stringstream(str), &bash_ast::parser_all_expansions); + libbash_value = ast.interpret_with(*walker, &bash_ast::walker_string_expr); + }; + var_expansion returns[std::string libbash_value] @declarations { using namespace boost::xpressive; sregex replace_pattern; bool greedy; } - :^(USE_DEFAULT_WHEN_UNSET_OR_NULL var_name libbash_word=word) { + :^(USE_DEFAULT_WHEN_UNSET_OR_NULL var_name libbash_word=raw_string) { libbash_value = walker->do_default_expansion($var_name.libbash_value, libbash_word, $var_name.index); } - |^(ASSIGN_DEFAULT_WHEN_UNSET_OR_NULL var_name libbash_word=word) { + |^(ASSIGN_DEFAULT_WHEN_UNSET_OR_NULL var_name libbash_word=raw_string) { libbash_value = walker->do_assign_expansion($var_name.libbash_value, libbash_word, $var_name.index); } - |^(USE_ALTERNATE_WHEN_UNSET_OR_NULL var_name libbash_word=word) { + |^(USE_ALTERNATE_WHEN_UNSET_OR_NULL var_name libbash_word=raw_string) { libbash_value = walker->do_alternate_expansion($var_name.libbash_value, libbash_word, $var_name.index); } |(^(OFFSET array_name arithmetics arithmetics)) => ^(OFFSET libbash_name=array_name offset=arithmetics length=arithmetics) { @@ -485,24 +496,24 @@ var_expansion returns[std::string libbash_value] libbash_value = boost::lexical_cast<std::string>(walker->get_array_length(libbash_name)); } )) - |^(REPLACE_ALL var_name bash_pattern[replace_pattern, true] (replacement=string_expr)?) { + |^(REPLACE_ALL var_name bash_pattern[replace_pattern, true] (libbash_word=raw_string)?) { libbash_value = walker->do_replace_expansion($var_name.libbash_value, std::bind(&interpreter::replace_all, std::placeholders::_1, replace_pattern, - replacement.libbash_value), + libbash_word), $var_name.index); } - |^(REPLACE_AT_END var_name bash_pattern[replace_pattern, true] (replacement=string_expr)?) { + |^(REPLACE_AT_END var_name bash_pattern[replace_pattern, true] (libbash_word=raw_string)?) { replace_pattern = sregex(replace_pattern >> eos); libbash_value = walker->do_replace_expansion($var_name.libbash_value, std::bind(&interpreter::replace_all, std::placeholders::_1, replace_pattern, - replacement.libbash_value), + libbash_word), $var_name.index); } - |^(LAZY_REMOVE_AT_END var_name bash_pattern[replace_pattern, false] (replacement=string_expr)?) { + |^(LAZY_REMOVE_AT_END var_name bash_pattern[replace_pattern, false] (libbash_word=raw_string)?) { replace_pattern = sregex(bos >> (s1=*_) >> replace_pattern >> eos); libbash_value = walker->do_replace_expansion($var_name.libbash_value, std::bind(&interpreter::lazy_remove_at_end, @@ -511,21 +522,21 @@ var_expansion returns[std::string libbash_value] $var_name.index); } |^((REPLACE_AT_START { greedy = true; }|LAZY_REMOVE_AT_START { greedy = false; }) - var_name bash_pattern[replace_pattern, greedy] (replacement=string_expr)?) { + var_name bash_pattern[replace_pattern, greedy] (libbash_word=raw_string)?) { replace_pattern = sregex(bos >> replace_pattern); libbash_value = walker->do_replace_expansion($var_name.libbash_value, std::bind(&interpreter::replace_all, std::placeholders::_1, replace_pattern, - replacement.libbash_value), + libbash_word), $var_name.index); } - |^(REPLACE_FIRST var_name bash_pattern[replace_pattern, true] (replacement=string_expr)?) { + |^(REPLACE_FIRST var_name bash_pattern[replace_pattern, true] (libbash_word=raw_string)?) { libbash_value = walker->do_replace_expansion($var_name.libbash_value, std::bind(&interpreter::replace_first, std::placeholders::_1, replace_pattern, - replacement.libbash_value), + libbash_word), $var_name.index); }; diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp index 3787f84..213264c 100644 --- a/src/core/bash_ast.cpp +++ b/src/core/bash_ast.cpp @@ -211,6 +211,11 @@ long bash_ast::walker_arithmetics(plibbashWalker tree_parser) return tree_parser->arithmetics(tree_parser); } +std::string bash_ast::walker_string_expr(libbashWalker_Ctx_struct* tree_parser) +{ + return tree_parser->string_expr(tree_parser).libbash_value; +} + pANTLR3_BASE_TREE bash_ast::parser_start(plibbashParser parser) { return parser->start(parser).tree; @@ -221,6 +226,11 @@ pANTLR3_BASE_TREE bash_ast::parser_arithmetics(plibbashParser parser) return parser->arithmetics(parser).tree; } +pANTLR3_BASE_TREE bash_ast::parser_all_expansions(libbashParser_Ctx_struct* parser) +{ + return parser->all_expansions(parser).tree; +} + void bash_ast::call_function(plibbashWalker ctx, ANTLR3_MARKER index) { diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h index 1dd7be2..8aa291a 100644 --- a/src/core/bash_ast.h +++ b/src/core/bash_ast.h @@ -92,6 +92,10 @@ public: /// \param tree_parser the pointer to the tree_parser static long walker_arithmetics(libbashWalker_Ctx_struct* tree_parser); + /// \brief the functor for walker string_expr rule + /// \param tree_parser the pointer to the tree_parser + static std::string walker_string_expr(libbashWalker_Ctx_struct* tree_parser); + /// \brief call a function that is defined in the AST /// \param tree_parser the pointer to the tree_parser /// \param index the function index @@ -106,6 +110,10 @@ public: /// \param parser the pointer to the parser static pANTLR3_BASE_TREE parser_arithmetics(libbashParser_Ctx_struct* parser); + /// \brief the functor for parser all_expansions rule + /// \param parser the pointer to the parser + static pANTLR3_BASE_TREE parser_all_expansions(libbashParser_Ctx_struct* parser); + /// /// \brief interpret the script with a given interpreter /// \param walker the interpreter object |