aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMu Qiao <qiaomuf@gentoo.org>2012-03-02 16:01:49 +0800
committerMu Qiao <qiaomuf@gentoo.org>2012-03-02 16:01:49 +0800
commite6d7f3a96a8850199da5d71d717243333943549c (patch)
treed48f234fca9ad253782f52965448b20300d3f048
parentWalker: allow bash expansions in regular expressions (diff)
downloadlibbash-e6d7f3a96a8850199da5d71d717243333943549c.tar.gz
libbash-e6d7f3a96a8850199da5d71d717243333943549c.tar.bz2
libbash-e6d7f3a96a8850199da5d71d717243333943549c.zip
Parser&Walker: support literals in regular exp
-rw-r--r--bashast/bashast.g10
-rw-r--r--bashast/gunit/cond_main.gunit1
-rw-r--r--bashast/libbashWalker.g3
-rw-r--r--scripts/var_expansion.bash3
-rw-r--r--src/core/bash_ast.cpp15
-rw-r--r--src/core/bash_ast.h6
6 files changed, 25 insertions, 13 deletions
diff --git a/bashast/bashast.g b/bashast/bashast.g
index 92f4f92..c6d7f34 100644
--- a/bashast/bashast.g
+++ b/bashast/bashast.g
@@ -80,6 +80,7 @@ tokens{
BRANCH;
MATCH_PATTERN;
MATCH_REGULAR_EXPRESSION;
+ ESCAPED_CHAR;
NOT_MATCH_PATTERN;
MATCH_ANY;
MATCH_ANY_EXCEPT;
@@ -651,13 +652,20 @@ scope {
}
:(
DQUOTE! { $bash_pattern_part::quoted = !$bash_pattern_part::quoted; }
- | {$bash_pattern_part::quoted}? => ~DQUOTE
+ | {$bash_pattern_part::quoted}? => preserved_tokens
| (ESC BLANK) => ESC BLANK
| LPAREN { if(LA(-2) != ESC) $bash_pattern_part::parens++; }
| LLPAREN { if(LA(-2) != ESC) $bash_pattern_part::parens += 2; }
| {$bash_pattern_part::parens != 0}? => RPAREN { if(LA(-2) != ESC) $bash_pattern_part::parens--; }
| ~(BLANK|EOL|LOGICAND|LOGICOR|LPAREN|RPAREN|DQUOTE|LLPAREN)
)+;
+
+preserved_tokens
+ : non_dquote -> ESCAPED_CHAR non_dquote;
+
+non_dquote
+ : ~DQUOTE;
+
keyword_binary_string_operator
: BLANK! binary_operator BLANK!
| BLANK! EQUALS BLANK!
diff --git a/bashast/gunit/cond_main.gunit b/bashast/gunit/cond_main.gunit
index cb8ffef..b6f339b 100644
--- a/bashast/gunit/cond_main.gunit
+++ b/bashast/gunit/cond_main.gunit
@@ -31,6 +31,7 @@ condition_expr:
"[ a == b ]" -> (BUILTIN_TEST (= (STRING a) (STRING b)))
"[ a != b ]" -> (BUILTIN_TEST (NOT_EQUALS (STRING a) (STRING b)))
"[[ \"${DISTUTILS_SRC_TEST}\" =~ ^(setup\.py|nosetests|py\.test|trial(\ .*)?)$ ]]" -> (KEYWORD_TEST (MATCH_REGULAR_EXPRESSION (STRING (DOUBLE_QUOTED_STRING (VAR_REF DISTUTILS_SRC_TEST))) (STRING ^ ( setup \ . py | nosetests | py \ . test | trial ( \ . * ) ? ) $)))
+"[[ a =~ \" \"bcd ]]" -> (KEYWORD_TEST (MATCH_REGULAR_EXPRESSION (STRING a) (STRING ESCAPED_CHAR bcd)))
"[ -n \"$FROM_LANG\" -a -n \"$TO_LANG\" ]" -> (BUILTIN_TEST (BUILTIN_LOGIC_AND (n (STRING (DOUBLE_QUOTED_STRING (VAR_REF FROM_LANG)))) (n (STRING (DOUBLE_QUOTED_STRING (VAR_REF TO_LANG))))))
"[ -n \"$FROM_LANG\" -o -n \"$TO_LANG\" ]" -> (BUILTIN_TEST (BUILTIN_LOGIC_OR (n (STRING (DOUBLE_QUOTED_STRING (VAR_REF FROM_LANG)))) (n (STRING (DOUBLE_QUOTED_STRING (VAR_REF TO_LANG))))))
"[ -n \"a\" -o -n \"a\" -a -n \"a\" ]" -> (BUILTIN_TEST (BUILTIN_LOGIC_OR (n (STRING (DOUBLE_QUOTED_STRING a))) (BUILTIN_LOGIC_AND (n (STRING (DOUBLE_QUOTED_STRING a))) (n (STRING (DOUBLE_QUOTED_STRING a))))))
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index d45d9c3..f57f403 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -302,6 +302,7 @@ string_part returns[std::string libbash_value, bool quoted, bool is_raw_string]
$libbash_value = transformed.str();
$quoted = true;
}
+ |(ESCAPED_CHAR) => ESCAPED_CHAR libbash_string=any_string { $libbash_value = "\\" + libbash_string; }
|(libbash_string=any_string {
$libbash_value = libbash_string;
});
@@ -797,7 +798,7 @@ keyword_condition returns[bool status]
} r=keyword_condition) { $status= l && r; }
|^(NEGATION l=keyword_condition) { $status = !l; }
|^(MATCH_REGULAR_EXPRESSION left_str=string_expr right_str=string_expr) {
- bash_ast ast(std::stringstream(right_str.libbash_value), &bash_ast::parser_all_expansions);
+ bash_ast ast(std::stringstream(right_str.libbash_value), &bash_ast::parser_all_expansions, false);
std::string pattern = ast.interpret_with(*walker, &bash_ast::walker_string_expr);
boost::xpressive::sregex re = boost::xpressive::sregex::compile(pattern);
$status = boost::xpressive::regex_match(left_str.libbash_value, re);
diff --git a/scripts/var_expansion.bash b/scripts/var_expansion.bash
index 4bdcb3e..97e9587 100644
--- a/scripts/var_expansion.bash
+++ b/scripts/var_expansion.bash
@@ -135,8 +135,6 @@ root=123
echo "${search_paths/%/${root}}"
echo "${search_paths/#/${root}}"
-# This regular expression will cause boost::exception_detail::clone_impl<boost::xpressive::regex_error>
-#[[ "${version_components_groups}" =~ ("*".*" "|" *"|^2.*\ (2|\*)|^3.*\ (3|\*)) ]]
[[ " ${FUNCNAME[@]:2} " =~ " "(_python_final_sanity_checks|python_execute_function|python_mod_optimize|python_mod_cleanup)" " ]]
[[ "$(declare -p PYTHON_SANITY_CHECKS_EXECUTED)" != "declare -- PYTHON_SANITY_CHECKS_EXECUTED="* || " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " && -z "${PYTHON_SKIP_SANITY_CHECKS}" ]]
[[ " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " ]]
@@ -146,3 +144,4 @@ PYTHON_DEPEND="2:2.6"
version_components_group_regex="(2|3|\*)(:([[:digit:]]+\.[[:digit:]]+)?(:([[:digit:]]+\.[[:digit:]]+)?)?)?"
version_components_groups="${PYTHON_DEPEND}"
[[ "${version_components_groups}" =~ ^((\!)?[[:alnum:]_-]+\?\ )?${version_components_group_regex}(\ ${version_components_group_regex})?$ ]] && echo true
+[[ "${version_components_groups}" =~ ("*".*" "|" *"|^2.*\ (2|\*)|^3.*\ (3|\*)) ]] && echo true
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp
index 5cca4f4..23571ef 100644
--- a/src/core/bash_ast.cpp
+++ b/src/core/bash_ast.cpp
@@ -36,31 +36,34 @@
#include "libbashParser.h"
#include "libbashWalker.h"
-void bash_ast::read_script(const std::istream& source)
+void bash_ast::read_script(const std::istream& source, bool trim)
{
std::stringstream stream;
stream << source.rdbuf();
script = stream.str();
boost::algorithm::erase_all(script, "\\\n");
- boost::trim_if(script, boost::is_any_of(" \t\n"));
+ if(trim)
+ boost::trim_if(script, boost::is_any_of(" \t\n"));
}
bash_ast::bash_ast(const std::istream& source,
- std::function<pANTLR3_BASE_TREE(plibbashParser)> p): parse(p)
+ std::function<pANTLR3_BASE_TREE(plibbashParser)> p,
+ bool trim): parse(p)
{
- read_script(source);
+ read_script(source, trim);
init_parser("unknown source");
}
bash_ast::bash_ast(const std::string& script_path,
- std::function<pANTLR3_BASE_TREE(plibbashParser)> p): parse(p)
+ std::function<pANTLR3_BASE_TREE(plibbashParser)> p,
+ bool trim): parse(p)
{
std::stringstream stream;
std::ifstream file_stream(script_path);
if(!file_stream)
throw libbash::parse_exception(script_path + " can't be read");
- read_script(file_stream);
+ read_script(file_stream, trim);
init_parser(script_path);
}
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h
index 50ca7a6..073553c 100644
--- a/src/core/bash_ast.h
+++ b/src/core/bash_ast.h
@@ -67,7 +67,7 @@ class bash_ast: public boost::noncopyable
typedef std::unique_ptr<libbashWalker_Ctx_struct, std::function<void(libbashWalker_Ctx_struct*)>> walker_pointer;
- void read_script(const std::istream& source);
+ void read_script(const std::istream& source, bool trim);
void init_parser(const std::string& script_path);
walker_pointer create_walker(interpreter& walker,
antlr_pointer<ANTLR3_COMMON_TREE_NODE_STREAM_struct>& nodes);
@@ -77,13 +77,13 @@ public:
/// \param source input source
/// \param p the parser rule for building the AST
bash_ast(const std::istream& source,
- std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start);
+ std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start, bool trim=true);
/// \brief build AST from string
/// \param script_path input source
/// \param p the parser rule for building the AST
bash_ast(const std::string& script_path,
- std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start);
+ std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start, bool trim=true);
/// \brief the functor for walker start rule
/// \param tree_parser the pointer to the tree_parser