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 /bashast
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
Diffstat (limited to 'bashast')
-rw-r--r--bashast/bashast.g10
-rw-r--r--bashast/gunit/cond_main.gunit1
-rw-r--r--bashast/libbashWalker.g3
3 files changed, 12 insertions, 2 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);