public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/libbash:master commit in: scripts/, bashast/, test/, bashast/gunit/, bashast/features_script/
@ 2011-07-20 13:08 Petteri Räty
  0 siblings, 0 replies; only message in thread
From: Petteri Räty @ 2011-07-20 13:08 UTC (permalink / raw
  To: gentoo-commits

commit:     3c33fa7935f0ba4294241944295b343f8165412d
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Wed Jul  6 14:08:44 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Wed Jul 20 08:29:56 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=3c33fa79

Parser: handle command substitution in lexer rules

Inside command substitution, many characters are allowed. For example,
MY_PV="$(replace_version_separator 1 '')" will reserve the single quotes
for command substitution. Now we support this by handling command
substitution in the lexer rules and call back to parser in walker
grammar.

---
 bashast/bashast.g                                 |   32 +++++++++++++++++++-
 bashast/features_script/features.sh.ast           |    2 +-
 bashast/features_script/features.sh.tokens        |   10 +++---
 bashast/features_script/features.sh.walker.tokens |    2 +-
 bashast/gunit/array.gunit                         |    4 +-
 bashast/gunit/command_sub.gunit                   |   10 +++---
 bashast/gunit/compound.gunit                      |   14 ++++----
 bashast/gunit/expansions.gunit                    |    2 +-
 bashast/gunit/fname.gunit                         |    6 ++--
 bashast/gunit/simp_prog.gunit                     |    2 +-
 bashast/libbashWalker.g                           |   12 ++++++--
 scripts/command_execution.bash                    |    4 ++
 test/post_check.cpp                               |    2 +-
 13 files changed, 70 insertions(+), 32 deletions(-)

diff --git a/bashast/bashast.g b/bashast/bashast.g
index c69edea..1b4548e 100644
--- a/bashast/bashast.g
+++ b/bashast/bashast.g
@@ -126,6 +126,7 @@ tokens{
 		return input.LA(index);
 	}
 #endif
+	int paren_level = 0;
 }
 
 #ifdef OUTPUT_C
@@ -297,8 +298,8 @@ brace_expansion_part
 	|	-> ^(STRING);
 commasep:	brace_expansion_part(COMMA! brace_expansion_part)+;
 command_sub
-	:	DOLLAR LPAREN clist BLANK? RPAREN -> ^(COMMAND_SUB clist)
-	|	TICK clist BLANK? TICK -> ^(COMMAND_SUB clist) ;
+	:	COMMAND_SUBSTITUTION_PAREN -> ^(COMMAND_SUB COMMAND_SUBSTITUTION_PAREN)
+	|	COMMAND_SUBSTITUTION_TICK -> ^(COMMAND_SUB COMMAND_SUBSTITUTION_TICK);
 //compound commands
 compound_command
 	:	for_expr
@@ -767,6 +768,33 @@ ESC_RPAREN
 	:	ESC RPAREN;
 ESC_LPAREN
 	:	ESC LPAREN;
+ESC_DOLLAR
+	:	ESC DOLLAR;
+ESC_TICK
+	:	ESC TICK;
+COMMAND_SUBSTITUTION_PAREN
+	:
+		{LA(1) == '$' && LA(2) == '(' && LA(3) != '('}?
+		=> (DOLLAR LPAREN ({ paren_level = 1; }
+			(
+				ESC_LPAREN
+				|ESC_RPAREN
+				|LPAREN { ++paren_level; }
+				|RPAREN { if(--paren_level == 0) {
+#ifdef OUTPUT_C
+						LEXSTATE->type = _type;
+#else
+						state.type = _type;
+						state.channel = _channel;
+#endif
+						return;
+					}
+				}
+				|.
+			)+
+		));
+COMMAND_SUBSTITUTION_TICK
+	:	TICK (~(TICK))+ TICK;
 ESC_LT	:	ESC'<';
 ESC_GT	:	ESC'>';
 //Handle ANSI C escaped characters: escaped octal, escaped hex, escaped ctrl+ chars, then all others

diff --git a/bashast/features_script/features.sh.ast b/bashast/features_script/features.sh.ast
index ad37b9c..26c634d 100644
--- a/bashast/features_script/features.sh.ast
+++ b/bashast/features_script/features.sh.ast
@@ -1 +1 @@
-(LIST (COMMAND (function (STRING lots_o_echo) (CURRENT_SHELL (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING The   number   of   tests   that   have   failed :   (VAR_REF failedtests)))) (COMMAND (STRING echo) (STRING (SINGLE_QUOTED_STRING '$failedtests'))) (COMMAND (STRING echo) (STRING (VAR_REF failedtests))))))) (COMMAND (function (STRING do_some_arith) (CURRENT_SHELL (LIST (COMMAND (ARITHMETIC_EXPRESSION (* 5 4))) (COMMAND (ARITHMETIC_EXPRESSION (** 5 4))) (COMMAND (ARITHMETIC_EXPRESSION (+ (VAR_REF failedtests) (/ 5 4)))) (COMMAND (ARITHMETIC_EXPRESSION (+ (VAR_REF z) (MINUS_SIGN 3)))))))) (COMMAND (function (STRING arrays) (SUBSHELL (LIST (COMMAND (VARIABLE_DEFINITIONS (= asdf (ARRAY (STRING a) (STRING b) (STRING c) (STRING d))))) (COMMAND (STRING echo) (STRING (VAR_REF (asdf 3)))) (COMMAND (VARIABLE_DEFINITIONS (= foo (ARRAY (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING 6))))) (STRING b) (STRING c) (STRING d))))) (COMMAND (VARIABLE_DEFINITIONS (
 = (arr (VAR_REF foo)) (STRING 3)))) (COMMAND (VARIABLE_DEFINITIONS (= bar (ARRAY (STRING a) (STRING b) (= 5 (STRING c)))))))))) (COMMAND (STRING echo) (STRING (BRACE_EXP (STRING a) (STRING b)))) (COMMAND (STRING echo) (STRING (BRACE_EXP (.. a d)))) (COMMAND (STRING echo) (STRING (BRACE_EXP (STRING (BRACE_EXP (STRING a) (STRING b))) (STRING c) (STRING d)))) (COMMAND (STRING echo) (STRING a (BRACE_EXP (STRING b) (STRING c)))) (COMMAND (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING foobar)))))) (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING gunit) (REDIR >> (STRING filelist)))) (COMMAND (case (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING asdf))))) (CASE_PATTERN (STRING gz) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING yay)))) (CASE_PATTERN (STRING bzip) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING three)))) (CASE_PATTERN (STRING MATCH_ALL) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING woo)))))) (COMMAND (for each (STRING (COMMAND_SUB
  (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING log)))))) (LIST (COMMAND (STRING echo) (STRING (VAR_REF each))) (COMMAND (STRING cat) (STRING each))))) (COMMAND (CFOR (FOR_INIT (+ 5 3)) (FOR_COND (+ 6 2)) (LIST (COMMAND (STRING echo) (STRING yay))) (FOR_MOD (+ 3 1)))) (COMMAND (select each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING output)))))) (LIST (COMMAND (STRING echo) (STRING asdf) (STRING 2) (REDIR > (STRING / dev / null)))))) (COMMAND (IF_STATEMENT (if (LIST (COMMAND (STRING echo) (STRING yay2))) (LIST (COMMAND (STRING echo) (STRING yay)))))) (COMMAND (until (LIST (COMMAND (COMPOUND_COND (KEYWORD_TEST (a (STRING this / is . afile)))))) (LIST (COMMAND (STRING touch) (STRING this / is . afile))))) (COMMAND (while (LIST (COMMAND (COMPOUND_COND (BUILTIN_TEST (n (STRING foobar)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))) (COMMAND (IF_STATEMENT (if (LIST (COMMAND (COMPOUND_COND (BU
 ILTIN_TEST (eq (STRING 5) (STRING 6)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING something ' s   wrong))))))) (COMMAND (STRING echo) (STRING this) (STRING command) (STRING has) (STRING multiple) (STRING arguments)) (COMMAND (STRING wc) (PROCESS_SUBSTITUTION < (LIST (COMMAND (STRING cat) (STRING / usr / share / dict / linux . words))))) (|| (&& (&& (&& (COMMAND (STRING cd) (STRING build)) (COMMAND (STRING . / configure))) (COMMAND (STRING make))) (COMMAND (STRING make_install))) (COMMAND (STRING echo) (STRING fail))) (COMMAND (STRING cd) (STRING / usr / bin)) (| (COMMAND (STRING ls) (STRING - al)) (COMMAND (STRING grep) (STRING more))) (COMMAND (VARIABLE_DEFINITIONS (= asdf (STRING parameters)))) (COMMAND (STRING (VAR_REF (USE_DEFAULT_WHEN_UNSET_OR_NULL asdf (STRING foo))))) (COMMAND (STRING (VAR_REF (OFFSET asdf 8)))) (COMMAND (STRING (VAR_REF (! asdf *)))) (COMMAND (STRING (VAR_REF (! asdf @)))) (COMMAND (STRING (VAR_REF (# foo)))) (COMMAND (STRING (VAR_
 REF (REPLACE_FIRST replaice (STRING with) (STRING pattern))))) (COMMAND (STRING (VAR_REF (LAZY_REMOVE_AT_START asdf (STRING bar))))) (COMMAND (STRING (VAR_REF (REPLACE_AT_START asdf (STRING bar))))) (COMMAND (STRING (VAR_REF (LAZY_REMOVE_AT_END asdf (STRING bar))))) (COMMAND (STRING (VAR_REF (LAZY_REMOVE_AT_END asdf (STRING bar))))) (COMMAND (STRING (VAR_REF 1)) (STRING (VAR_REF @)) (STRING (VAR_REF *))) (COMMAND (STRING (VAR_REF ?))) (COMMAND (STRING (VAR_REF (REPLACE_ALL PV (STRING .) (STRING _))))) (COMMAND (STRING (VAR_REF (REPLACE_AT_START PV (STRING foo) (STRING bar))))) (COMMAND (STRING (VAR_REF (REPLACE_AT_END PV (STRING foo) (STRING bar))))) (COMMAND (VARIABLE_DEFINITIONS (= MY_PN (STRING (VAR_REF (REPLACE_FIRST PN (STRING asterisk -))))))) (| (COMMAND (STRING cat) (STRING asdf)) (COMMAND (STRING grep) (STRING three) (STRING 2) (REDIR >& (FILE_DESCRIPTOR 1)) (REDIR > (STRING / dev / null)))) (COMMAND (STRING echo) (STRING asdf) (REDIR >> (STRING APPEND))) (COMMAND (
 STRING echo) (STRING cat) (<<< (STRING word))))
+(LIST (COMMAND (function (STRING lots_o_echo) (CURRENT_SHELL (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING The   number   of   tests   that   have   failed :   (VAR_REF failedtests)))) (COMMAND (STRING echo) (STRING (SINGLE_QUOTED_STRING '$failedtests'))) (COMMAND (STRING echo) (STRING (VAR_REF failedtests))))))) (COMMAND (function (STRING do_some_arith) (CURRENT_SHELL (LIST (COMMAND (ARITHMETIC_EXPRESSION (* 5 4))) (COMMAND (ARITHMETIC_EXPRESSION (** 5 4))) (COMMAND (ARITHMETIC_EXPRESSION (+ (VAR_REF failedtests) (/ 5 4)))) (COMMAND (ARITHMETIC_EXPRESSION (+ (VAR_REF z) (MINUS_SIGN 3)))))))) (COMMAND (function (STRING arrays) (SUBSHELL (LIST (COMMAND (VARIABLE_DEFINITIONS (= asdf (ARRAY (STRING a) (STRING b) (STRING c) (STRING d))))) (COMMAND (STRING echo) (STRING (VAR_REF (asdf 3)))) (COMMAND (VARIABLE_DEFINITIONS (= foo (ARRAY (STRING (COMMAND_SUB `echo 6`)) (STRING b) (STRING c) (STRING d))))) (COMMAND (VARIABLE_DEFINITIONS (= (arr (VAR_REF foo)) (STRING 3))
 )) (COMMAND (VARIABLE_DEFINITIONS (= bar (ARRAY (STRING a) (STRING b) (= 5 (STRING c)))))))))) (COMMAND (STRING echo) (STRING (BRACE_EXP (STRING a) (STRING b)))) (COMMAND (STRING echo) (STRING (BRACE_EXP (.. a d)))) (COMMAND (STRING echo) (STRING (BRACE_EXP (STRING (BRACE_EXP (STRING a) (STRING b))) (STRING c) (STRING d)))) (COMMAND (STRING echo) (STRING a (BRACE_EXP (STRING b) (STRING c)))) (COMMAND (STRING (COMMAND_SUB $(echo foobar)))) (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING gunit) (REDIR >> (STRING filelist)))) (COMMAND (case (STRING (COMMAND_SUB `echo asdf`)) (CASE_PATTERN (STRING gz) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING yay)))) (CASE_PATTERN (STRING bzip) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING three)))) (CASE_PATTERN (STRING MATCH_ALL) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING woo)))))) (COMMAND (for each (STRING (COMMAND_SUB `ls |grep log`)) (LIST (COMMAND (STRING echo) (STRING (VAR_REF each))) (COMMAND (STRING cat) (STR
 ING each))))) (COMMAND (CFOR (FOR_INIT (+ 5 3)) (FOR_COND (+ 6 2)) (LIST (COMMAND (STRING echo) (STRING yay))) (FOR_MOD (+ 3 1)))) (COMMAND (select each (STRING (COMMAND_SUB `ls |grep output`)) (LIST (COMMAND (STRING echo) (STRING asdf) (STRING 2) (REDIR > (STRING / dev / null)))))) (COMMAND (IF_STATEMENT (if (LIST (COMMAND (STRING echo) (STRING yay2))) (LIST (COMMAND (STRING echo) (STRING yay)))))) (COMMAND (until (LIST (COMMAND (COMPOUND_COND (KEYWORD_TEST (a (STRING this / is . afile)))))) (LIST (COMMAND (STRING touch) (STRING this / is . afile))))) (COMMAND (while (LIST (COMMAND (COMPOUND_COND (BUILTIN_TEST (n (STRING foobar)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))) (COMMAND (IF_STATEMENT (if (LIST (COMMAND (COMPOUND_COND (BUILTIN_TEST (eq (STRING 5) (STRING 6)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING something ' s   wrong))))))) (COMMAND (STRING echo) (STRING this) (STRING command) (STRING has) (STRING mul
 tiple) (STRING arguments)) (COMMAND (STRING wc) (PROCESS_SUBSTITUTION < (LIST (COMMAND (STRING cat) (STRING / usr / share / dict / linux . words))))) (|| (&& (&& (&& (COMMAND (STRING cd) (STRING build)) (COMMAND (STRING . / configure))) (COMMAND (STRING make))) (COMMAND (STRING make_install))) (COMMAND (STRING echo) (STRING fail))) (COMMAND (STRING cd) (STRING / usr / bin)) (| (COMMAND (STRING ls) (STRING - al)) (COMMAND (STRING grep) (STRING more))) (COMMAND (VARIABLE_DEFINITIONS (= asdf (STRING parameters)))) (COMMAND (STRING (VAR_REF (USE_DEFAULT_WHEN_UNSET_OR_NULL asdf (STRING foo))))) (COMMAND (STRING (VAR_REF (OFFSET asdf 8)))) (COMMAND (STRING (VAR_REF (! asdf *)))) (COMMAND (STRING (VAR_REF (! asdf @)))) (COMMAND (STRING (VAR_REF (# foo)))) (COMMAND (STRING (VAR_REF (REPLACE_FIRST replaice (STRING with) (STRING pattern))))) (COMMAND (STRING (VAR_REF (LAZY_REMOVE_AT_START asdf (STRING bar))))) (COMMAND (STRING (VAR_REF (REPLACE_AT_START asdf (STRING bar))))) (COMMAND 
 (STRING (VAR_REF (LAZY_REMOVE_AT_END asdf (STRING bar))))) (COMMAND (STRING (VAR_REF (LAZY_REMOVE_AT_END asdf (STRING bar))))) (COMMAND (STRING (VAR_REF 1)) (STRING (VAR_REF @)) (STRING (VAR_REF *))) (COMMAND (STRING (VAR_REF ?))) (COMMAND (STRING (VAR_REF (REPLACE_ALL PV (STRING .) (STRING _))))) (COMMAND (STRING (VAR_REF (REPLACE_AT_START PV (STRING foo) (STRING bar))))) (COMMAND (STRING (VAR_REF (REPLACE_AT_END PV (STRING foo) (STRING bar))))) (COMMAND (VARIABLE_DEFINITIONS (= MY_PN (STRING (VAR_REF (REPLACE_FIRST PN (STRING asterisk -))))))) (| (COMMAND (STRING cat) (STRING asdf)) (COMMAND (STRING grep) (STRING three) (STRING 2) (REDIR >& (FILE_DESCRIPTOR 1)) (REDIR > (STRING / dev / null)))) (COMMAND (STRING echo) (STRING asdf) (REDIR >> (STRING APPEND))) (COMMAND (STRING echo) (STRING cat) (<<< (STRING word))))

diff --git a/bashast/features_script/features.sh.tokens b/bashast/features_script/features.sh.tokens
index 104a000..25c95d3 100644
--- a/bashast/features_script/features.sh.tokens
+++ b/bashast/features_script/features.sh.tokens
@@ -38,7 +38,7 @@
 38	FUNCTION BLANK NAME LPAREN RPAREN BLANK LPAREN EOL
 39	BLANK NAME EQUALS LPAREN LETTER BLANK LETTER BLANK LETTER BLANK LETTER RPAREN EOL
 40	BLANK NAME BLANK DOLLAR LBRACE NAME LSQUARE DIGIT RSQUARE RBRACE EOL
-41	BLANK NAME EQUALS LPAREN TICK NAME BLANK DIGIT TICK BLANK LETTER BLANK LETTER BLANK LETTER RPAREN EOL
+41	BLANK NAME EQUALS LPAREN COMMAND_SUBSTITUTION_TICK BLANK LETTER BLANK LETTER BLANK LETTER RPAREN EOL
 42	BLANK NAME LSQUARE NAME RSQUARE EQUALS DIGIT EOL
 43	BLANK NAME EQUALS LPAREN LETTER BLANK LETTER BLANK LSQUARE DIGIT RSQUARE EQUALS LETTER RPAREN SEMIC EOL
 44	RPAREN EOL
@@ -48,10 +48,10 @@
 48	NAME BLANK LBRACE LBRACE LETTER COMMA LETTER RBRACE COMMA LETTER COMMA LETTER RBRACE EOL
 49	NAME BLANK LETTER LBRACE LETTER COMMA LETTER RBRACE EOL
 50	
-51	DOLLAR LPAREN NAME BLANK NAME RPAREN EOL
+51	COMMAND_SUBSTITUTION_PAREN EOL
 52	NAME BLANK PIPE NAME BLANK NAME BLANK RSHIFT BLANK NAME EOL
 53	
-54	CASE BLANK TICK NAME BLANK NAME TICK BLANK IN EOL
+54	CASE BLANK COMMAND_SUBSTITUTION_TICK BLANK IN EOL
 55	NAME RPAREN EOL
 56	NAME BLANK NAME EOL
 57	DOUBLE_SEMIC EOL
@@ -62,14 +62,14 @@
 62	DOUBLE_SEMIC EOL
 63	ESAC EOL
 64	
-65	FOR BLANK NAME BLANK IN BLANK TICK NAME BLANK PIPE NAME BLANK NAME TICK SEMIC BLANK DO EOL
+65	FOR BLANK NAME BLANK IN BLANK COMMAND_SUBSTITUTION_TICK SEMIC BLANK DO EOL
 66	BLANK NAME BLANK DOLLAR NAME EOL
 67	BLANK NAME BLANK NAME EOL
 68	DONE EOL
 69	
 70	FOR BLANK LLPAREN DIGIT PLUS DIGIT SEMIC DIGIT PLUS DIGIT SEMIC DIGIT PLUS DIGIT RPAREN RPAREN SEMIC BLANK DO BLANK NAME BLANK NAME SEMIC BLANK DONE EOL
 71	
-72	SELECT BLANK NAME BLANK IN BLANK TICK NAME BLANK PIPE NAME BLANK NAME TICK SEMIC BLANK DO EOL
+72	SELECT BLANK NAME BLANK IN BLANK COMMAND_SUBSTITUTION_TICK SEMIC BLANK DO EOL
 73	BLANK NAME BLANK NAME BLANK DIGIT GREATER_THAN BLANK SLASH NAME SLASH NAME EOL
 74	DONE EOL
 75	

diff --git a/bashast/features_script/features.sh.walker.tokens b/bashast/features_script/features.sh.walker.tokens
index 14b0536..ba1a405 100644
--- a/bashast/features_script/features.sh.walker.tokens
+++ b/bashast/features_script/features.sh.walker.tokens
@@ -1,2 +1,2 @@
-LIST DOWN COMMAND DOWN FUNCTION DOWN STRING DOWN NAME UP CURRENT_SHELL DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DOUBLE_QUOTED_STRING DOWN NAME BLANK NAME BLANK NAME BLANK NAME BLANK NAME BLANK NAME BLANK NAME COLON BLANK VAR_REF DOWN NAME UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN SINGLE_QUOTED_STRING DOWN SINGLE_QUOTED_STRING_TOKEN UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN VAR_REF DOWN NAME UP UP UP UP UP UP UP COMMAND DOWN FUNCTION DOWN STRING DOWN NAME UP CURRENT_SHELL DOWN LIST DOWN COMMAND DOWN ARITHMETIC_EXPRESSION DOWN TIMES DOWN DIGIT DIGIT UP UP UP COMMAND DOWN ARITHMETIC_EXPRESSION DOWN EXP DOWN DIGIT DIGIT UP UP UP COMMAND DOWN ARITHMETIC_EXPRESSION DOWN PLUS DOWN VAR_REF DOWN NAME UP SLASH DOWN DIGIT DIGIT UP UP UP UP COMMAND DOWN ARITHMETIC_EXPRESSION DOWN PLUS DOWN VAR_REF DOWN LETTER UP MINUS_SIGN DOWN DIGIT UP UP UP UP UP UP UP UP COMMAND DOWN FUNCTION DOWN STRING DOWN NAME UP SUBSHELL DOWN LIST DOWN COMMAND DOWN V
 ARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME ARRAY DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN VAR_REF DOWN NAME DOWN DIGIT UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME ARRAY DOWN STRING DOWN COMMAND_SUB DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DIGIT UP UP UP UP UP STRING DOWN LETTER UP STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME DOWN VAR_REF DOWN NAME UP UP STRING DOWN DIGIT UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME ARRAY DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP EQUALS DOWN DIGIT STRING DOWN LETTER UP UP UP UP UP UP UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN BRACE_EXP DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN BRACE_EXP DOWN DOTDOT DOWN LETTER LETTER UP UP UP
  UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN BRACE_EXP DOWN STRING DOWN BRACE_EXP DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN LETTER BRACE_EXP DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP COMMAND DOWN STRING DOWN COMMAND_SUB DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP PIPE DOWN COMMAND DOWN STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP REDIR DOWN OP STRING DOWN NAME UP UP UP UP COMMAND DOWN CASE DOWN STRING DOWN COMMAND_SUB DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP CASE_PATTERN DOWN STRING DOWN NAME UP CASE_COMMAND LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP CASE_PATTERN DOWN STRING DOWN NAME UP CASE_COMMAND LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP CASE_PATTERN DOWN STRING DOWN MATCH_ALL 
 UP CASE_COMMAND LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP COMMAND DOWN FOR DOWN NAME STRING DOWN COMMAND_SUB DOWN LIST DOWN PIPE DOWN COMMAND DOWN STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN VAR_REF DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN CFOR DOWN FOR_INIT DOWN PLUS DOWN DIGIT DIGIT UP UP FOR_COND DOWN PLUS DOWN DIGIT DIGIT UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP FOR_MOD DOWN PLUS DOWN DIGIT DIGIT UP UP UP UP COMMAND DOWN SELECT DOWN NAME STRING DOWN COMMAND_SUB DOWN LIST DOWN PIPE DOWN COMMAND DOWN STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN DIGIT UP REDIR DOWN GREATER_THAN STRING DOWN SLASH NAME SLASH NAME UP UP UP UP UP UP CO
 MMAND DOWN IF_STATEMENT DOWN IF DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP COMMAND DOWN UNTIL DOWN LIST DOWN COMMAND DOWN COMPOUND_COND DOWN KEYWORD_TEST DOWN LETTER DOWN STRING DOWN NAME SLASH NAME DOT NAME UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME SLASH NAME DOT NAME UP UP UP UP UP COMMAND DOWN WHILE DOWN LIST DOWN COMMAND DOWN COMPOUND_COND DOWN BUILTIN_TEST DOWN LETTER DOWN STRING DOWN NAME UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DOUBLE_QUOTED_STRING DOWN NAME BLANK NAME UP UP UP UP UP UP COMMAND DOWN IF_STATEMENT DOWN IF DOWN LIST DOWN COMMAND DOWN COMPOUND_COND DOWN BUILTIN_TEST DOWN NAME DOWN STRING DOWN DIGIT UP STRING DOWN DIGIT UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DOUBLE_QUOTED_STRING DOWN NAME SQUOTE LETTER BLANK NAME UP UP UP UP UP UP UP COMMAND DOWN ST
 RING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP PROCESS_SUBSTITUTION DOWN LESS_THAN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN SLASH NAME SLASH NAME SLASH NAME SLASH NAME DOT NAME UP UP UP UP UP LOGICOR DOWN LOGICAND DOWN LOGICAND DOWN LOGICAND DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN DOT SLASH NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN SLASH NAME SLASH NAME UP UP PIPE DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN MINUS NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME STRING DOWN NAME UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN USE_DEFAULT_WHEN_UNSET_OR_NULL DOWN NAME STRING DOWN
  NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN OFFSET DOWN NAME DIGIT UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN BANG DOWN NAME TIMES UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN BANG DOWN NAME AT UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN POUND DOWN NAME UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_FIRST DOWN NAME STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN LAZY_REMOVE_AT_START DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_AT_START DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN LAZY_REMOVE_AT_END DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN LAZY_REMOVE_AT_END DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN DIGIT UP UP STRING DOWN VAR_REF DOWN AT UP UP STRING DOWN VAR_REF DOWN TIMES UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN QMARK UP UP UP COM
 MAND DOWN STRING DOWN VAR_REF DOWN REPLACE_ALL DOWN NAME STRING DOWN DOT UP STRING DOWN UNDERSCORE UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_AT_START DOWN NAME STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_AT_END DOWN NAME STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME STRING DOWN VAR_REF DOWN REPLACE_FIRST DOWN NAME STRING DOWN NAME MINUS UP UP UP UP UP UP UP PIPE DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN DIGIT UP REDIR DOWN OP FILE_DESCRIPTOR DOWN DIGIT UP UP REDIR DOWN GREATER_THAN STRING DOWN SLASH NAME SLASH NAME UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP REDIR DOWN OP STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP HERE_STRING_OP DOWN STRING DOWN NAME UP UP UP UP 
+LIST DOWN COMMAND DOWN FUNCTION DOWN STRING DOWN NAME UP CURRENT_SHELL DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DOUBLE_QUOTED_STRING DOWN NAME BLANK NAME BLANK NAME BLANK NAME BLANK NAME BLANK NAME BLANK NAME COLON BLANK VAR_REF DOWN NAME UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN SINGLE_QUOTED_STRING DOWN SINGLE_QUOTED_STRING_TOKEN UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN VAR_REF DOWN NAME UP UP UP UP UP UP UP COMMAND DOWN FUNCTION DOWN STRING DOWN NAME UP CURRENT_SHELL DOWN LIST DOWN COMMAND DOWN ARITHMETIC_EXPRESSION DOWN TIMES DOWN DIGIT DIGIT UP UP UP COMMAND DOWN ARITHMETIC_EXPRESSION DOWN EXP DOWN DIGIT DIGIT UP UP UP COMMAND DOWN ARITHMETIC_EXPRESSION DOWN PLUS DOWN VAR_REF DOWN NAME UP SLASH DOWN DIGIT DIGIT UP UP UP UP COMMAND DOWN ARITHMETIC_EXPRESSION DOWN PLUS DOWN VAR_REF DOWN LETTER UP MINUS_SIGN DOWN DIGIT UP UP UP UP UP UP UP UP COMMAND DOWN FUNCTION DOWN STRING DOWN NAME UP SUBSHELL DOWN LIST DOWN COMMAND DOWN V
 ARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME ARRAY DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN VAR_REF DOWN NAME DOWN DIGIT UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME ARRAY DOWN STRING DOWN COMMAND_SUB DOWN COMMAND_SUBSTITUTION_TICK UP UP STRING DOWN LETTER UP STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME DOWN VAR_REF DOWN NAME UP UP STRING DOWN DIGIT UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME ARRAY DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP EQUALS DOWN DIGIT STRING DOWN LETTER UP UP UP UP UP UP UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN BRACE_EXP DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN BRACE_EXP DOWN DOTDOT DOWN LETTER LETTER UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING 
 DOWN BRACE_EXP DOWN STRING DOWN BRACE_EXP DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN LETTER BRACE_EXP DOWN STRING DOWN LETTER UP STRING DOWN LETTER UP UP UP UP COMMAND DOWN STRING DOWN COMMAND_SUB DOWN COMMAND_SUBSTITUTION_PAREN UP UP UP PIPE DOWN COMMAND DOWN STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP REDIR DOWN OP STRING DOWN NAME UP UP UP UP COMMAND DOWN CASE DOWN STRING DOWN COMMAND_SUB DOWN COMMAND_SUBSTITUTION_TICK UP UP CASE_PATTERN DOWN STRING DOWN NAME UP CASE_COMMAND LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP CASE_PATTERN DOWN STRING DOWN NAME UP CASE_COMMAND LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP CASE_PATTERN DOWN STRING DOWN MATCH_ALL UP CASE_COMMAND LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP COMMAND DOWN FOR DOWN NAME STRING D
 OWN COMMAND_SUB DOWN COMMAND_SUBSTITUTION_TICK UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN VAR_REF DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN CFOR DOWN FOR_INIT DOWN PLUS DOWN DIGIT DIGIT UP UP FOR_COND DOWN PLUS DOWN DIGIT DIGIT UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP FOR_MOD DOWN PLUS DOWN DIGIT DIGIT UP UP UP UP COMMAND DOWN SELECT DOWN NAME STRING DOWN COMMAND_SUB DOWN COMMAND_SUBSTITUTION_TICK UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN DIGIT UP REDIR DOWN GREATER_THAN STRING DOWN SLASH NAME SLASH NAME UP UP UP UP UP UP COMMAND DOWN IF_STATEMENT DOWN IF DOWN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP UP COMMAND DOWN UNTIL DOWN LIST DOWN COMMAND DOWN COMPOUND_COND DOWN KEYWORD_TEST DOWN LETTER DOWN STRING DOWN NAME SLASH NAME DOT N
 AME UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME SLASH NAME DOT NAME UP UP UP UP UP COMMAND DOWN WHILE DOWN LIST DOWN COMMAND DOWN COMPOUND_COND DOWN BUILTIN_TEST DOWN LETTER DOWN STRING DOWN NAME UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DOUBLE_QUOTED_STRING DOWN NAME BLANK NAME UP UP UP UP UP UP COMMAND DOWN IF_STATEMENT DOWN IF DOWN LIST DOWN COMMAND DOWN COMPOUND_COND DOWN BUILTIN_TEST DOWN NAME DOWN STRING DOWN DIGIT UP STRING DOWN DIGIT UP UP UP UP UP UP LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN DOUBLE_QUOTED_STRING DOWN NAME SQUOTE LETTER BLANK NAME UP UP UP UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP PROCESS_SUBSTITUTION DOWN LESS_THAN LIST DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN SLASH NAME SLASH NAME SLASH NAME SLASH NAME DOT NAME UP UP UP UP UP 
 LOGICOR DOWN LOGICAND DOWN LOGICAND DOWN LOGICAND DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN DOT SLASH NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN SLASH NAME SLASH NAME UP UP PIPE DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN MINUS NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME STRING DOWN NAME UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN USE_DEFAULT_WHEN_UNSET_OR_NULL DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN OFFSET DOWN NAME DIGIT UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN BANG DOWN NAME TIMES UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN BANG DOWN NAME AT UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN POUND DOWN NAME UP UP UP UP COMMAND DOWN S
 TRING DOWN VAR_REF DOWN REPLACE_FIRST DOWN NAME STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN LAZY_REMOVE_AT_START DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_AT_START DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN LAZY_REMOVE_AT_END DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN LAZY_REMOVE_AT_END DOWN NAME STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN DIGIT UP UP STRING DOWN VAR_REF DOWN AT UP UP STRING DOWN VAR_REF DOWN TIMES UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN QMARK UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_ALL DOWN NAME STRING DOWN DOT UP STRING DOWN UNDERSCORE UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_AT_START DOWN NAME STRING DOWN NAME UP STRING DOWN NAME UP UP UP UP UP COMMAND DOWN STRING DOWN VAR_REF DOWN REPLACE_AT_END DOWN NAME STRING DOWN NAME UP
  STRING DOWN NAME UP UP UP UP UP COMMAND DOWN VARIABLE_DEFINITIONS DOWN EQUALS DOWN NAME STRING DOWN VAR_REF DOWN REPLACE_FIRST DOWN NAME STRING DOWN NAME MINUS UP UP UP UP UP UP UP PIPE DOWN COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP STRING DOWN DIGIT UP REDIR DOWN OP FILE_DESCRIPTOR DOWN DIGIT UP UP REDIR DOWN GREATER_THAN STRING DOWN SLASH NAME SLASH NAME UP UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP REDIR DOWN OP STRING DOWN NAME UP UP UP COMMAND DOWN STRING DOWN NAME UP STRING DOWN NAME UP HERE_STRING_OP DOWN STRING DOWN NAME UP UP UP UP 
 

diff --git a/bashast/gunit/array.gunit b/bashast/gunit/array.gunit
index ce0b344..0a176eb 100644
--- a/bashast/gunit/array.gunit
+++ b/bashast/gunit/array.gunit
@@ -20,9 +20,9 @@ gunit java_libbash;
 
 var_def:
 "asdf=(a b c d)"->(= asdf (ARRAY (STRING a) (STRING b) (STRING c) (STRING d)))
-"asdf=(`echo 6` b c d)"-> (= asdf (ARRAY (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING 6))))) (STRING b) (STRING c) (STRING d)))
+"asdf=(`echo 6` b c d)"-> (= asdf (ARRAY (STRING (COMMAND_SUB `echo 6`)) (STRING b) (STRING c) (STRING d)))
 "asdf=(${P} b c d)"->(= asdf (ARRAY (STRING (VAR_REF P)) (STRING b) (STRING c) (STRING d)))
-"asdf=($(echo a))" -> (= asdf (ARRAY (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING a)))))))
+"asdf=($(echo a))" -> (= asdf (ARRAY (STRING (COMMAND_SUB $(echo a)))))
 "asdf=(
 		--disable-dependency-tracking
 		${VAR}

diff --git a/bashast/gunit/command_sub.gunit b/bashast/gunit/command_sub.gunit
index e2d0021..49c5844 100644
--- a/bashast/gunit/command_sub.gunit
+++ b/bashast/gunit/command_sub.gunit
@@ -19,8 +19,8 @@
 gunit java_libbash;
 
 command_sub:
-"$(echo \"foo\")" -> (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING foo)))))
-"$(ls |grep file)" -> (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING file)))))
-"$(CONTROL= command arg )" -> (COMMAND_SUB (LIST (COMMAND (STRING command) (STRING arg) (= CONTROL))))
-"`cat output.log |grep error|cut`" -> (COMMAND_SUB (LIST (| (| (COMMAND (STRING cat) (STRING output . log)) (COMMAND (STRING grep) (STRING error))) (COMMAND (STRING cut)))))
-"$(function foo() { echo 'hello'; }; foo)" -> (COMMAND_SUB (LIST (COMMAND (function (STRING foo) (CURRENT_SHELL (LIST (COMMAND (STRING echo) (STRING (SINGLE_QUOTED_STRING 'hello'))))))) (COMMAND (STRING foo))))
+"$(echo \"foo\")" -> (COMMAND_SUB $(echo "foo"))
+"$(ls |grep file)" -> (COMMAND_SUB $(ls |grep file))
+"$(CONTROL= command arg )" -> (COMMAND_SUB $(CONTROL= command arg ))
+"`cat output.log |grep error|cut`" -> (COMMAND_SUB `cat output.log |grep error|cut`)
+"$(function foo() { echo 'hello'; }; foo)" -> (COMMAND_SUB $(function foo() { echo 'hello'; }; foo))

diff --git a/bashast/gunit/compound.gunit b/bashast/gunit/compound.gunit
index 5e2a098..bf98197 100644
--- a/bashast/gunit/compound.gunit
+++ b/bashast/gunit/compound.gunit
@@ -54,7 +54,7 @@ subshell:
 case_expr:
 "case a in esac" -> (case (STRING a))
 "case `echo asdf` in
-esac" -> (case (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING asdf))))))
+esac" -> (case (STRING (COMMAND_SUB `echo asdf`)))
 
 "case `echo asdf` in
 gz)
@@ -65,7 +65,7 @@ echo three
 ;;
 *) echo woo
 ;;
-esac" -> (case (STRING (COMMAND_SUB (LIST (COMMAND (STRING echo) (STRING asdf))))) (CASE_PATTERN (STRING gz) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING yay)))) (CASE_PATTERN (STRING bzip) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING three)))) (CASE_PATTERN (STRING MATCH_ALL) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING woo)))))
+esac" -> (case (STRING (COMMAND_SUB `echo asdf`)) (CASE_PATTERN (STRING gz) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING yay)))) (CASE_PATTERN (STRING bzip) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING three)))) (CASE_PATTERN (STRING MATCH_ALL) CASE_COMMAND (LIST (COMMAND (STRING echo) (STRING woo)))))
 
 "case asdf in
 	gz)
@@ -83,8 +83,8 @@ esac" -> (case (STRING asdf) (CASE_PATTERN (STRING gz) CASE_COMMAND (LIST (COMMA
 for_expr:
 "for each in `ls |grep log`; do
 	echo \"file found\"
-done" -> (for each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING log)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
-"for each in `ls |grep log`; do echo \"file found\"; done" -> (for each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING log)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
+done" -> (for each (STRING (COMMAND_SUB `ls |grep log`)) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
+"for each in `ls |grep log`; do echo \"file found\"; done" -> (for each (STRING (COMMAND_SUB `ls |grep log`)) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
 "for i in 'foo' 'bar'; do echo $i; done" -> (for i (STRING (SINGLE_QUOTED_STRING 'foo')) (STRING (SINGLE_QUOTED_STRING 'bar')) (LIST (COMMAND (STRING echo) (STRING (VAR_REF i)))))
 "for i in foo$var bar; do echo $i; done" -> (for i (STRING foo (VAR_REF var)) (STRING bar) (LIST (COMMAND (STRING echo) (STRING (VAR_REF i)))))
 "for each in `ls |grep log`; do echo file done" FAIL
@@ -97,8 +97,8 @@ done" -> (for each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND
 sel_expr:
 "select each in `ls |grep log`; do
   echo \"file found\"
-	done" -> (select each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING log)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
-"select each in `ls |grep log`; do echo \"file found\"; done" -> (select each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING log)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
+	done" -> (select each (STRING (COMMAND_SUB `ls |grep log`)) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
+"select each in `ls |grep log`; do echo \"file found\"; done" -> (select each (STRING (COMMAND_SUB `ls |grep log`)) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found)))))
 "select each in `ls |grep log`; do echo file done" FAIL
 
 if_expr:
@@ -185,7 +185,7 @@ command:
 "case a in esac >/dev/null" -> (COMMAND (case (STRING a)) (REDIR > (STRING / dev / null)))
 "for i in foo$var bar; do echo $i; done >/dev/null" -> (COMMAND (for i (STRING foo (VAR_REF var)) (STRING bar) (LIST (COMMAND (STRING echo) (STRING (VAR_REF i))))) (REDIR > (STRING / dev / null)))
 "for ((5+3;;5+3)); do echo yay; done >/dev/null" -> (COMMAND (CFOR (FOR_INIT (+ 5 3)) (LIST (COMMAND (STRING echo) (STRING yay))) (FOR_MOD (+ 5 3))) (REDIR > (STRING / dev / null)))
-"select each in `ls |grep log`; do echo \"file found\"; done >/dev/null" -> (COMMAND (select each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING log)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found))))) (REDIR > (STRING / dev / null)))
+"select each in `ls |grep log`; do echo \"file found\"; done >/dev/null" -> (COMMAND (select each (STRING (COMMAND_SUB `ls |grep log`)) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file   found))))) (REDIR > (STRING / dev / null)))
 
 "if echo yay2;
 then

diff --git a/bashast/gunit/expansions.gunit b/bashast/gunit/expansions.gunit
index a36d4da..b10931d 100644
--- a/bashast/gunit/expansions.gunit
+++ b/bashast/gunit/expansions.gunit
@@ -26,5 +26,5 @@ clist:
 "[[ while = while ]] && echo true" -> (LIST (&& (COMMAND (COMPOUND_COND (KEYWORD_TEST (= (STRING while) (STRING while))))) (COMMAND (STRING echo) (STRING true))))
 "for each in `ls |grep output`; do
 echo $each
-done" -> (LIST (COMMAND (for each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING output)))))) (LIST (COMMAND (STRING echo) (STRING (VAR_REF each)))))))
+done" -> (LIST (COMMAND (for each (STRING (COMMAND_SUB `ls |grep output`)) (LIST (COMMAND (STRING echo) (STRING (VAR_REF each)))))))
 "wc <(cat /usr/share/dict/linux.words)" -> (LIST (COMMAND (STRING wc) (PROCESS_SUBSTITUTION < (LIST (COMMAND (STRING cat) (STRING / usr / share / dict / linux . words))))))

diff --git a/bashast/gunit/fname.gunit b/bashast/gunit/fname.gunit
index eb13235..882afd1 100644
--- a/bashast/gunit/fname.gunit
+++ b/bashast/gunit/fname.gunit
@@ -25,8 +25,8 @@ fname:
 "\"\"" -> (STRING DOUBLE_QUOTED_STRING)
 "\"For more info on this patchset, and how to report problems, see:\"" -> (STRING (DOUBLE_QUOTED_STRING For   more   info   on   this   patchset ,   and   how   to   report   problems ,   see :))
 "\"asdf;!\"" -> (STRING (DOUBLE_QUOTED_STRING asdf ; !))
-"\"$(whoami)\"" -> (STRING (DOUBLE_QUOTED_STRING (COMMAND_SUB (LIST (COMMAND (STRING whoami))))))
-"\"`whoami`\"" -> (STRING (DOUBLE_QUOTED_STRING (COMMAND_SUB (LIST (COMMAND (STRING whoami))))))
+"\"$(whoami)\"" -> (STRING (DOUBLE_QUOTED_STRING (COMMAND_SUB $(whoami))))
+"\"`whoami`\"" -> (STRING (DOUBLE_QUOTED_STRING (COMMAND_SUB `whoami`)))
 "'`whoami`'" -> (STRING (SINGLE_QUOTED_STRING '`whoami`'))
 "'$(whoami)'" -> (STRING (SINGLE_QUOTED_STRING '$(whoami)'))
 "\"${P}\"" -> (STRING (DOUBLE_QUOTED_STRING (VAR_REF P)))
@@ -72,4 +72,4 @@ fname:
 "\"abc#$/\"" -> (STRING (DOUBLE_QUOTED_STRING abc # $ /))
 
 dqstr:
-"\"\\\\\"\$\`\"" -> (DOUBLE_QUOTED_STRING \ " $ `)
+"\"\\\\\"\$\`\"" -> (DOUBLE_QUOTED_STRING \ " \$ \`)

diff --git a/bashast/gunit/simp_prog.gunit b/bashast/gunit/simp_prog.gunit
index 64aa001..d36c5f6 100644
--- a/bashast/gunit/simp_prog.gunit
+++ b/bashast/gunit/simp_prog.gunit
@@ -25,7 +25,7 @@ echo \"I found a file\"
 done
 
 echo \"finding complete\"
-"-> (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING finding   file))) (COMMAND (for each (STRING (COMMAND_SUB (LIST (| (COMMAND (STRING ls)) (COMMAND (STRING grep) (STRING output)))))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING I   found   a   file)))))) (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING finding   complete))))
+"-> (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING finding   file))) (COMMAND (for each (STRING (COMMAND_SUB `ls | grep output`)) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING I   found   a   file)))))) (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING finding   complete))))
 
 "function quit {
   exit

diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index 1edf10d..76c62d6 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -48,6 +48,7 @@ options
 	#include <boost/algorithm/string/join.hpp>
 
 	#include "builtins/builtin_exceptions.h"
+	#include "core/bash_ast.h"
 	#include "core/bash_condition.h"
 	#include "core/interpreter.h"
 	#include "cppbash_builtin.h"
@@ -285,7 +286,7 @@ string_part returns[std::string libbash_value, bool quoted, bool is_raw_string]
 		$libbash_value = libbash_string;
 		$is_raw_string = false;
 	}
-	|libbash_string=command_substitution {
+	|(COMMAND_SUB) => libbash_string=command_substitution {
 		$libbash_value = libbash_string;
 		$is_raw_string = false;
 	}
@@ -409,7 +410,7 @@ double_quoted_string returns[std::string libbash_value]
 	|(ARITHMETIC_EXPRESSION) => ^(ARITHMETIC_EXPRESSION value=arithmetics) {
 		$libbash_value = boost::lexical_cast<std::string>(value);
 	}
-	|libbash_string=command_substitution {
+	|(COMMAND_SUB) => libbash_string=command_substitution {
 		$libbash_value = libbash_string;
 	}
 	|libbash_string=any_string { $libbash_value = libbash_string; };
@@ -994,9 +995,14 @@ case_clause[const std::string& target] returns[bool matched]
 
 command_substitution returns[std::string libbash_value]
 @declarations {
+	std::string subscript;
 	std::stringstream out;
 }
-	:^(COMMAND_SUB{ walker->set_output_stream(&out); } command_list) {
+	:^(COMMAND_SUB { walker->set_output_stream(&out); } (libbash_string=any_string { subscript += libbash_string; })+) {
+		if(subscript[0] == '`')
+			bash_ast(std::stringstream(subscript.substr(1, subscript.size() - 2))).interpret_with(*walker);
+		else
+			bash_ast(std::stringstream(subscript.substr(2, subscript.size() - 3))).interpret_with(*walker);
 		walker->restore_output_stream();
 		$libbash_value = out.str();
 		walker->trim_trailing_eols($libbash_value);

diff --git a/scripts/command_execution.bash b/scripts/command_execution.bash
index 3d138fd..aa7f717 100644
--- a/scripts/command_execution.bash
+++ b/scripts/command_execution.bash
@@ -65,3 +65,7 @@ echo "abc #av### ##" # for comment
 echo $'abc\tdef\nxyz'
 echo -e "\'\"\t\n"
 echo 'quotes should be handled correctly'
+echo "$(echo 'hi')"
+echo "`echo 'hi'`"
+array=(`echo 1` `echo 2` 3)
+echo ${array[@]}

diff --git a/test/post_check.cpp b/test/post_check.cpp
index 715ccf5..2113926 100644
--- a/test/post_check.cpp
+++ b/test/post_check.cpp
@@ -35,7 +35,7 @@ static void check_file_size(const char *path, uintmax_t size_max)
 
 TEST(post_check, lexer_size)
 {
-  check_file_size("libbashLexer.cpp", 1024 * 1024);
+  check_file_size("libbashLexer.cpp", 2 * 1024 * 1024);
 }
 
 TEST(post_check, parser_size)



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2011-07-20 13:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-20 13:08 [gentoo-commits] proj/libbash:master commit in: scripts/, bashast/, test/, bashast/gunit/, bashast/features_script/ Petteri Räty

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox