1 |
commit: e6d7f3a96a8850199da5d71d717243333943549c |
2 |
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Mar 2 08:01:49 2012 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Mar 2 08:01:49 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=e6d7f3a9 |
7 |
|
8 |
Parser&Walker: support literals in regular exp |
9 |
|
10 |
--- |
11 |
bashast/bashast.g | 10 +++++++++- |
12 |
bashast/gunit/cond_main.gunit | 1 + |
13 |
bashast/libbashWalker.g | 3 ++- |
14 |
scripts/var_expansion.bash | 3 +-- |
15 |
src/core/bash_ast.cpp | 15 +++++++++------ |
16 |
src/core/bash_ast.h | 6 +++--- |
17 |
6 files changed, 25 insertions(+), 13 deletions(-) |
18 |
|
19 |
diff --git a/bashast/bashast.g b/bashast/bashast.g |
20 |
index 92f4f92..c6d7f34 100644 |
21 |
--- a/bashast/bashast.g |
22 |
+++ b/bashast/bashast.g |
23 |
@@ -80,6 +80,7 @@ tokens{ |
24 |
BRANCH; |
25 |
MATCH_PATTERN; |
26 |
MATCH_REGULAR_EXPRESSION; |
27 |
+ ESCAPED_CHAR; |
28 |
NOT_MATCH_PATTERN; |
29 |
MATCH_ANY; |
30 |
MATCH_ANY_EXCEPT; |
31 |
@@ -651,13 +652,20 @@ scope { |
32 |
} |
33 |
:( |
34 |
DQUOTE! { $bash_pattern_part::quoted = !$bash_pattern_part::quoted; } |
35 |
- | {$bash_pattern_part::quoted}? => ~DQUOTE |
36 |
+ | {$bash_pattern_part::quoted}? => preserved_tokens |
37 |
| (ESC BLANK) => ESC BLANK |
38 |
| LPAREN { if(LA(-2) != ESC) $bash_pattern_part::parens++; } |
39 |
| LLPAREN { if(LA(-2) != ESC) $bash_pattern_part::parens += 2; } |
40 |
| {$bash_pattern_part::parens != 0}? => RPAREN { if(LA(-2) != ESC) $bash_pattern_part::parens--; } |
41 |
| ~(BLANK|EOL|LOGICAND|LOGICOR|LPAREN|RPAREN|DQUOTE|LLPAREN) |
42 |
)+; |
43 |
+ |
44 |
+preserved_tokens |
45 |
+ : non_dquote -> ESCAPED_CHAR non_dquote; |
46 |
+ |
47 |
+non_dquote |
48 |
+ : ~DQUOTE; |
49 |
+ |
50 |
keyword_binary_string_operator |
51 |
: BLANK! binary_operator BLANK! |
52 |
| BLANK! EQUALS BLANK! |
53 |
|
54 |
diff --git a/bashast/gunit/cond_main.gunit b/bashast/gunit/cond_main.gunit |
55 |
index cb8ffef..b6f339b 100644 |
56 |
--- a/bashast/gunit/cond_main.gunit |
57 |
+++ b/bashast/gunit/cond_main.gunit |
58 |
@@ -31,6 +31,7 @@ condition_expr: |
59 |
"[ a == b ]" -> (BUILTIN_TEST (= (STRING a) (STRING b))) |
60 |
"[ a != b ]" -> (BUILTIN_TEST (NOT_EQUALS (STRING a) (STRING b))) |
61 |
"[[ \"${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 ( \ . * ) ? ) $))) |
62 |
+"[[ a =~ \" \"bcd ]]" -> (KEYWORD_TEST (MATCH_REGULAR_EXPRESSION (STRING a) (STRING ESCAPED_CHAR bcd))) |
63 |
"[ -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)))))) |
64 |
"[ -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)))))) |
65 |
"[ -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)))))) |
66 |
|
67 |
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g |
68 |
index d45d9c3..f57f403 100644 |
69 |
--- a/bashast/libbashWalker.g |
70 |
+++ b/bashast/libbashWalker.g |
71 |
@@ -302,6 +302,7 @@ string_part returns[std::string libbash_value, bool quoted, bool is_raw_string] |
72 |
$libbash_value = transformed.str(); |
73 |
$quoted = true; |
74 |
} |
75 |
+ |(ESCAPED_CHAR) => ESCAPED_CHAR libbash_string=any_string { $libbash_value = "\\" + libbash_string; } |
76 |
|(libbash_string=any_string { |
77 |
$libbash_value = libbash_string; |
78 |
}); |
79 |
@@ -797,7 +798,7 @@ keyword_condition returns[bool status] |
80 |
} r=keyword_condition) { $status= l && r; } |
81 |
|^(NEGATION l=keyword_condition) { $status = !l; } |
82 |
|^(MATCH_REGULAR_EXPRESSION left_str=string_expr right_str=string_expr) { |
83 |
- bash_ast ast(std::stringstream(right_str.libbash_value), &bash_ast::parser_all_expansions); |
84 |
+ bash_ast ast(std::stringstream(right_str.libbash_value), &bash_ast::parser_all_expansions, false); |
85 |
std::string pattern = ast.interpret_with(*walker, &bash_ast::walker_string_expr); |
86 |
boost::xpressive::sregex re = boost::xpressive::sregex::compile(pattern); |
87 |
$status = boost::xpressive::regex_match(left_str.libbash_value, re); |
88 |
|
89 |
diff --git a/scripts/var_expansion.bash b/scripts/var_expansion.bash |
90 |
index 4bdcb3e..97e9587 100644 |
91 |
--- a/scripts/var_expansion.bash |
92 |
+++ b/scripts/var_expansion.bash |
93 |
@@ -135,8 +135,6 @@ root=123 |
94 |
echo "${search_paths/%/${root}}" |
95 |
echo "${search_paths/#/${root}}" |
96 |
|
97 |
-# This regular expression will cause boost::exception_detail::clone_impl<boost::xpressive::regex_error> |
98 |
-#[[ "${version_components_groups}" =~ ("*".*" "|" *"|^2.*\ (2|\*)|^3.*\ (3|\*)) ]] |
99 |
[[ " ${FUNCNAME[@]:2} " =~ " "(_python_final_sanity_checks|python_execute_function|python_mod_optimize|python_mod_cleanup)" " ]] |
100 |
[[ "$(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}" ]] |
101 |
[[ " ${FUNCNAME[@]:1} " =~ " "(python_set_active_version|python_pkg_setup)" " ]] |
102 |
@@ -146,3 +144,4 @@ PYTHON_DEPEND="2:2.6" |
103 |
version_components_group_regex="(2|3|\*)(:([[:digit:]]+\.[[:digit:]]+)?(:([[:digit:]]+\.[[:digit:]]+)?)?)?" |
104 |
version_components_groups="${PYTHON_DEPEND}" |
105 |
[[ "${version_components_groups}" =~ ^((\!)?[[:alnum:]_-]+\?\ )?${version_components_group_regex}(\ ${version_components_group_regex})?$ ]] && echo true |
106 |
+[[ "${version_components_groups}" =~ ("*".*" "|" *"|^2.*\ (2|\*)|^3.*\ (3|\*)) ]] && echo true |
107 |
|
108 |
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp |
109 |
index 5cca4f4..23571ef 100644 |
110 |
--- a/src/core/bash_ast.cpp |
111 |
+++ b/src/core/bash_ast.cpp |
112 |
@@ -36,31 +36,34 @@ |
113 |
#include "libbashParser.h" |
114 |
#include "libbashWalker.h" |
115 |
|
116 |
-void bash_ast::read_script(const std::istream& source) |
117 |
+void bash_ast::read_script(const std::istream& source, bool trim) |
118 |
{ |
119 |
std::stringstream stream; |
120 |
stream << source.rdbuf(); |
121 |
script = stream.str(); |
122 |
boost::algorithm::erase_all(script, "\\\n"); |
123 |
- boost::trim_if(script, boost::is_any_of(" \t\n")); |
124 |
+ if(trim) |
125 |
+ boost::trim_if(script, boost::is_any_of(" \t\n")); |
126 |
} |
127 |
|
128 |
bash_ast::bash_ast(const std::istream& source, |
129 |
- std::function<pANTLR3_BASE_TREE(plibbashParser)> p): parse(p) |
130 |
+ std::function<pANTLR3_BASE_TREE(plibbashParser)> p, |
131 |
+ bool trim): parse(p) |
132 |
{ |
133 |
- read_script(source); |
134 |
+ read_script(source, trim); |
135 |
init_parser("unknown source"); |
136 |
} |
137 |
|
138 |
bash_ast::bash_ast(const std::string& script_path, |
139 |
- std::function<pANTLR3_BASE_TREE(plibbashParser)> p): parse(p) |
140 |
+ std::function<pANTLR3_BASE_TREE(plibbashParser)> p, |
141 |
+ bool trim): parse(p) |
142 |
{ |
143 |
std::stringstream stream; |
144 |
std::ifstream file_stream(script_path); |
145 |
if(!file_stream) |
146 |
throw libbash::parse_exception(script_path + " can't be read"); |
147 |
|
148 |
- read_script(file_stream); |
149 |
+ read_script(file_stream, trim); |
150 |
init_parser(script_path); |
151 |
} |
152 |
|
153 |
|
154 |
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h |
155 |
index 50ca7a6..073553c 100644 |
156 |
--- a/src/core/bash_ast.h |
157 |
+++ b/src/core/bash_ast.h |
158 |
@@ -67,7 +67,7 @@ class bash_ast: public boost::noncopyable |
159 |
|
160 |
typedef std::unique_ptr<libbashWalker_Ctx_struct, std::function<void(libbashWalker_Ctx_struct*)>> walker_pointer; |
161 |
|
162 |
- void read_script(const std::istream& source); |
163 |
+ void read_script(const std::istream& source, bool trim); |
164 |
void init_parser(const std::string& script_path); |
165 |
walker_pointer create_walker(interpreter& walker, |
166 |
antlr_pointer<ANTLR3_COMMON_TREE_NODE_STREAM_struct>& nodes); |
167 |
@@ -77,13 +77,13 @@ public: |
168 |
/// \param source input source |
169 |
/// \param p the parser rule for building the AST |
170 |
bash_ast(const std::istream& source, |
171 |
- std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start); |
172 |
+ std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start, bool trim=true); |
173 |
|
174 |
/// \brief build AST from string |
175 |
/// \param script_path input source |
176 |
/// \param p the parser rule for building the AST |
177 |
bash_ast(const std::string& script_path, |
178 |
- std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start); |
179 |
+ std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start, bool trim=true); |
180 |
|
181 |
/// \brief the functor for walker start rule |
182 |
/// \param tree_parser the pointer to the tree_parser |