aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMu Qiao <qiaomuf@gentoo.org>2012-02-23 15:58:27 +0800
committerMu Qiao <qiaomuf@gentoo.org>2012-02-23 16:20:16 +0800
commitf4bdbb24bdbcb12655005202dec2fc6e216f0ed3 (patch)
tree2c4efa82db56b6be2c8770f017df085ab46dff71
parentWalker: support shortcut in keyword test (diff)
downloadlibbash-f4bdbb24bdbcb12655005202dec2fc6e216f0ed3.tar.gz
libbash-f4bdbb24bdbcb12655005202dec2fc6e216f0ed3.tar.bz2
libbash-f4bdbb24bdbcb12655005202dec2fc6e216f0ed3.zip
Parser&Walker: respect precedence in builtin test
Builtin test does not support shortcut capability. Tests are added to verify that.
-rw-r--r--bashast/bashast.g28
-rw-r--r--bashast/gunit/cond_main.gunit5
-rw-r--r--bashast/libbashWalker.g13
-rw-r--r--scripts/test_expr.bash8
4 files changed, 37 insertions, 17 deletions
diff --git a/bashast/bashast.g b/bashast/bashast.g
index b383219..8286a00 100644
--- a/bashast/bashast.g
+++ b/bashast/bashast.g
@@ -126,7 +126,8 @@ tokens{
NOT_EQUALS;
EQUALS_TO;
- BUILTIN_LOGIC;
+ BUILTIN_LOGIC_AND;
+ BUILTIN_LOGIC_OR;
FUNCTION;
}
@@ -651,13 +652,16 @@ keyword_binary_string_operator
| BLANK!? LESS_THAN BLANK!?
| BLANK!? GREATER_THAN BLANK!?;
+
+builtin_condition_and
+ : builtin_condition_primary (builtin_logic_and^ BLANK! builtin_condition_primary)?;
builtin_condition
- : ((BANG) => builtin_negation_primary|builtin_keyword_condition_primary)
- (BLANK! builtin_logic_operator^ BLANK! builtin_condition)?;
+ : builtin_condition_and (builtin_logic_or^ BLANK! builtin_condition_and)?;
builtin_negation_primary
- : BANG BLANK builtin_keyword_condition_primary -> ^(NEGATION builtin_keyword_condition_primary);
-builtin_keyword_condition_primary
+ : BANG BLANK builtin_condition_primary -> ^(NEGATION builtin_condition_primary);
+builtin_condition_primary
: LPAREN! BLANK!? builtin_condition BLANK!? RPAREN!
+ | (BANG) => builtin_negation_primary
| (unary_operator) => builtin_condition_unary
| builtin_condition_binary;
builtin_condition_unary
@@ -671,8 +675,18 @@ builtin_binary_string_operator
| BANG EQUALS -> NOT_EQUALS
| ESC_LT
| ESC_GT;
-builtin_logic_operator
- : unary_operator -> ^(BUILTIN_LOGIC unary_operator);
+builtin_logic_and
+#ifdef OUTPUT_C
+ : {LA(1) == BLANK && LA(2) == MINUS && LA(3) == LETTER && "a" == get_string(LT(3))}?=> BLANK MINUS LETTER -> BUILTIN_LOGIC_AND;
+#else
+ : {LA(1) == BLANK && LA(2) == MINUS && LA(3) == LETTER && "a".equals(get_string(LT(3)))}?=> BLANK MINUS LETTER -> BUILTIN_LOGIC_AND;
+#endif
+builtin_logic_or
+#ifdef OUTPUT_C
+ : {LA(1) == BLANK && LA(2) == MINUS && LA(3) == LETTER && "o" == get_string(LT(3))}?=> BLANK MINUS LETTER -> BUILTIN_LOGIC_OR;
+#else
+ : {LA(1) == BLANK && LA(2) == MINUS && LA(3) == LETTER && "o".equals(get_string(LT(3)))}?=> BLANK MINUS LETTER -> BUILTIN_LOGIC_OR;
+#endif
binary_operator
: MINUS! NAME^;
diff --git a/bashast/gunit/cond_main.gunit b/bashast/gunit/cond_main.gunit
index 5ecd024..bf86d7d 100644
--- a/bashast/gunit/cond_main.gunit
+++ b/bashast/gunit/cond_main.gunit
@@ -31,8 +31,9 @@ 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 ( \ . * ) ? ) $)))
-"[ -n \"$FROM_LANG\" -a -n \"$TO_LANG\" ]" -> (BUILTIN_TEST (BUILTIN_LOGIC a (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 o (n (STRING (DOUBLE_QUOTED_STRING (VAR_REF FROM_LANG)))) (n (STRING (DOUBLE_QUOTED_STRING (VAR_REF TO_LANG))))))
+"[ -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))))))
"[[ \"${element}\" =~ (^[^[:space:]]+\ .) ]]" -> (KEYWORD_TEST (MATCH_REGULAR_EXPRESSION (STRING (DOUBLE_QUOTED_STRING (VAR_REF element))) (STRING ( ^ [ ^ [ : space : ] ] + \ . ))))
"[[ a<b ]]" -> (KEYWORD_TEST (< (STRING a) (STRING b)))
"[[ a>b ]]" -> (KEYWORD_TEST (> (STRING a) (STRING b)))
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index e357642..7c7afaf 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -786,14 +786,11 @@ keyword_condition returns[bool status]
builtin_condition returns[bool status]
:^(NEGATION l=builtin_condition) { $status = !l; }
- |^(BUILTIN_LOGIC o=LETTER l=builtin_condition r=builtin_condition) {
- char op = get_char(o);
- if(op == 'a')
- $status = l && r;
- else if(op == 'o')
- $status = l || r;
- else
- throw libbash::parse_exception(std::string("unrecognized operator in built-in test: ") + op);
+ |^(BUILTIN_LOGIC_AND l=builtin_condition r=builtin_condition) {
+ $status = l && r;
+ }
+ |^(BUILTIN_LOGIC_OR l=builtin_condition r=builtin_condition) {
+ $status = l || r;
}
|s=builtin_condition_primary { $status = s; };
diff --git a/scripts/test_expr.bash b/scripts/test_expr.bash
index 6ae7246..f8e7c03 100644
--- a/scripts/test_expr.bash
+++ b/scripts/test_expr.bash
@@ -61,3 +61,11 @@ i=1
[[ a == b && $((i=1)) ]] || echo $i # i should still be 0
i=1
[[ a == a && $((i=0)) ]] && echo $i # i should still be 0
+[ -n "a" -o -n "" -a -n "" ] && echo true
+# builtin test doesn't support shortcut
+i=1
+[ 1 -eq 2 -o $((i=0)) ] && echo $i # i should be 0 now
+[ 1 -eq 1 -o $((i=1)) ] && echo $i # i should still be 1
+[ 1 -eq 2 -a $((i=1)) ] || echo $i # i should still be 1
+i=1
+[ 1 -eq 1 -a $((i=0)) ] && echo $i # i should still be 0