diff options
author | Petteri Räty <petsku@petteriraty.eu> | 2011-06-25 13:26:05 +0300 |
---|---|---|
committer | Petteri Räty <petsku@petteriraty.eu> | 2011-06-25 13:26:05 +0300 |
commit | a0f1ce8a10a50a732a9aaec80a51df8f72120c78 (patch) | |
tree | 562072913ba113a4eeaef94a9eb3bded9f2a2453 | |
parent | Merge remote-tracking branch 'mu/break_builtin' (diff) | |
parent | Walker: support arithmetic expression (diff) | |
download | libbash-a0f1ce8a10a50a732a9aaec80a51df8f72120c78.tar.gz libbash-a0f1ce8a10a50a732a9aaec80a51df8f72120c78.tar.bz2 libbash-a0f1ce8a10a50a732a9aaec80a51df8f72120c78.zip |
Merge remote-tracking branch 'mu/fix_arithmetic'
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | bashast/bashast.g | 9 | ||||
-rw-r--r-- | bashast/features_script/features.sh.ast | 2 | ||||
-rw-r--r-- | bashast/features_script/features.sh.walker.tokens | 2 | ||||
-rw-r--r-- | bashast/gunit/compound.gunit | 10 | ||||
-rw-r--r-- | bashast/gunit/expansions.gunit | 4 | ||||
-rw-r--r-- | bashast/libbashWalker.g | 35 | ||||
-rw-r--r-- | scripts/binary_arithmetic.bash | 2 | ||||
-rw-r--r-- | scripts/binary_arithmetic.bash.result | 2 | ||||
-rw-r--r-- | scripts/command_execution.bash | 1 | ||||
-rw-r--r-- | scripts/command_execution.bash.result | 1 | ||||
-rw-r--r-- | src/core/bash_ast.cpp | 22 | ||||
-rw-r--r-- | src/core/bash_ast.h | 4 | ||||
-rwxr-xr-x | test/ast_printer_test.sh | 4 | ||||
-rw-r--r-- | utils/ast_printer.cpp | 40 |
15 files changed, 114 insertions, 25 deletions
diff --git a/Makefile.am b/Makefile.am index c00b784..403ecf4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -253,6 +253,7 @@ EXTRA_DIST = bashast/bashast.g \ bashast/features_script/features.sh \ bashast/features_script/features.sh.ast \ bashast/features_script/features.sh.tokens \ + bashast/features_script/features.sh.walker.tokens \ test/ast_printer_test.sh \ test/verify_bashs_test.sh \ test/verify_error_output_test.sh \ diff --git a/bashast/bashast.g b/bashast/bashast.g index d5ea5e3..1a73c4b 100644 --- a/bashast/bashast.g +++ b/bashast/bashast.g @@ -35,7 +35,6 @@ tokens{ CASE_COMMAND; SUBSHELL; CURRENT_SHELL; - COMPOUND_ARITH; COMPOUND_COND; CFOR; FOR_INIT; @@ -203,7 +202,7 @@ compound_command | case_expr | subshell | current_shell - | arith_comparison + | arithmetic_expression | cond_comparison; //Expressions allowed inside a compound command for_expr: FOR BLANK+ name (wspace IN (BLANK+ fname)+)? semiel DO wspace* clist semiel DONE -> ^(FOR name (fname+)? clist) @@ -236,9 +235,9 @@ subshell: LPAREN wspace? clist (BLANK* SEMIC)? (BLANK* EOL)* BLANK* RPAREN -> ^( //A grouping of commands executed in the current shell current_shell : LBRACE wspace clist semiel wspace* RBRACE -> ^(CURRENT_SHELL clist); -//comparison using arithmetic -arith_comparison - : LLPAREN wspace? arithmetic wspace? RPAREN RPAREN -> ^(COMPOUND_ARITH arithmetic); +//Bash arithmetic expression (( expression )) +arithmetic_expression + : LLPAREN wspace? arithmetic wspace? RPAREN RPAREN -> ^(ARITHMETIC_EXPRESSION arithmetic); cond_comparison : cond_expr -> ^(COMPOUND_COND cond_expr); //Variables diff --git a/bashast/features_script/features.sh.ast b/bashast/features_script/features.sh.ast index 7217880..4191c85 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 (COMPOUND_ARITH (* 5 4))) (COMMAND (COMPOUND_ARITH (** 5 4))) (COMMAND (COMPOUND_ARITH (+ (VAR_REF failedtests) (/ 5 4)))) (COMMAND (COMPOUND_ARITH (+ (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 (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 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 (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 (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 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)))) diff --git a/bashast/features_script/features.sh.walker.tokens b/bashast/features_script/features.sh.walker.tokens new file mode 100644 index 0000000..255caa7 --- /dev/null +++ b/bashast/features_script/features.sh.walker.tokens @@ -0,0 +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 DOLLAR NAME 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 VARIABLE_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 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 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 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 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 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/compound.gunit b/bashast/gunit/compound.gunit index c1e7a55..f4ca4e1 100644 --- a/bashast/gunit/compound.gunit +++ b/bashast/gunit/compound.gunit @@ -28,9 +28,9 @@ cond_comparison: "[[ asdf > qwert ]]" -> (COMPOUND_COND (KEYWORD_TEST (> (STRING asdf) (STRING qwert)))) "[ asdf \> qwert ]" -> (COMPOUND_COND (BUILTIN_TEST (\> (STRING asdf) (STRING qwert)))) -arith_comparison: -"((5+3))" -> (COMPOUND_ARITH (+ 5 3)) -"(( 5+3 ))" -> (COMPOUND_ARITH (+ 5 3)) +arithmetic_expression: +"((5+3))" -> (ARITHMETIC_EXPRESSION (+ 5 3)) +"(( 5+3 ))" -> (ARITHMETIC_EXPRESSION (+ 5 3)) current_shell: "{ time cat; }" -> (CURRENT_SHELL (LIST (COMMAND (STRING cat) time))) @@ -135,7 +135,7 @@ while_expr: echo \"file found\" done" -> (while (LIST (COMMAND (STRING echo) (STRING true))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file found))))) "while echo true; do echo \"file found\"; done" -> (while (LIST (COMMAND (STRING echo) (STRING true))) (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING file found))))) -"while(( 1>0 )); do echo ok; done" -> (while (LIST (COMMAND (COMPOUND_ARITH (> 1 0)))) (LIST (COMMAND (STRING echo) (STRING ok)))) +"while(( 1>0 )); do echo ok; done" -> (while (LIST (COMMAND (ARITHMETIC_EXPRESSION (> 1 0)))) (LIST (COMMAND (STRING echo) (STRING ok)))) "while echo true`; do echo file done" FAIL "while [[ -n \"$ver_str\" ]] ; do echo true @@ -179,7 +179,7 @@ esac" -> (case (STRING (DOUBLE_QUOTED_STRING (VAR_REF 1))) (CASE_PATTERN (STRING command: "[[ asdf > qwert ]] > /dev/null" -> (COMMAND (COMPOUND_COND (KEYWORD_TEST (> (STRING asdf) (STRING qwert)))) (REDIR > (STRING / dev / null))) -"(( 5+3 )) > /dev/null" -> (COMMAND (COMPOUND_ARITH (+ 5 3)) (REDIR > (STRING / dev / null))) +"(( 5+3 )) > /dev/null" -> (COMMAND (ARITHMETIC_EXPRESSION (+ 5 3)) (REDIR > (STRING / dev / null))) "{ time cat; } > /dev/null" -> (COMMAND (CURRENT_SHELL (LIST (COMMAND (STRING cat) time))) (REDIR > (STRING / dev / null))) "(time cat) > /dev/null" -> (COMMAND (SUBSHELL (LIST (COMMAND (STRING cat) time))) (REDIR > (STRING / dev / null))) "case a in esac >/dev/null" -> (COMMAND (case (STRING a)) (REDIR > (STRING / dev / null))) diff --git a/bashast/gunit/expansions.gunit b/bashast/gunit/expansions.gunit index 3cc5632..20c54f1 100644 --- a/bashast/gunit/expansions.gunit +++ b/bashast/gunit/expansions.gunit @@ -20,8 +20,8 @@ gunit bashast; clist: "echo a{b,c,d}" -> (LIST (COMMAND (STRING echo) (STRING a (BRACE_EXP (STRING b) (STRING c) (STRING d))))) -"((5+5))" -> (LIST (COMMAND (COMPOUND_ARITH (+ 5 5)))) -"(( 4 + asdf ))" -> (LIST (COMMAND (COMPOUND_ARITH (+ 4 (VAR_REF asdf))))) +"((5+5))" -> (LIST (COMMAND (ARITHMETIC_EXPRESSION (+ 5 5)))) +"(( 4 + asdf ))" -> (LIST (COMMAND (ARITHMETIC_EXPRESSION (+ 4 (VAR_REF asdf))))) "[[ while=while ]] && echo true" -> (LIST (&& (COMMAND (COMPOUND_COND (KEYWORD_TEST (STRING while = while)))) (COMMAND (STRING echo) (STRING true)))) "[[ 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 diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g index 835ec96..7121afa 100644 --- a/bashast/libbashWalker.g +++ b/bashast/libbashWalker.g @@ -72,7 +72,7 @@ options index = value; } - // seek to LT(2) and consume + // skip to next tree void seek_to_next_tree(plibbashWalker ctx) { // Current depth of the tree we are traversing @@ -96,6 +96,14 @@ options CONSUME(); } + void skip_next_token_or_tree(plibbashWalker ctx) + { + if(LA(2) != DOWN) + SEEK(INDEX() + 1); + else + seek_to_next_tree(ctx); + } + // The method is used to append a pattern with another one. Because it's not allowed to append an empty pattern, // we need the argument 'do_append' to indicate whether the pattern is empty. 'do_append' will be set to true after // the first assignment. @@ -642,6 +650,7 @@ command_list: ^(LIST logic_command_list+); compound_command : ^(CURRENT_SHELL command_list) | ^(COMPOUND_COND cond_expr) + | ^(ARITHMETIC_EXPRESSION arithmetics) | for_expr | while_expr | if_expr @@ -1009,8 +1018,28 @@ primary returns[std::string libbash_value, unsigned index] // shell arithmetic arithmetics returns[int value] - :^(LOGICOR l=arithmetics r=arithmetics) { $value = l || r; } - |^(LOGICAND l=arithmetics r=arithmetics) { $value = l && r; } + :^(LOGICOR l=arithmetics { + if(l) + { + skip_next_token_or_tree(ctx); + $value = 1; + } + else + { + $value = (arithmetics(ctx) != 0); + } + }) + |^(LOGICAND l=arithmetics { + if(!l) + { + skip_next_token_or_tree(ctx); + $value = 0; + } + else + { + $value = (arithmetics(ctx) != 0); + } + }) |^(PIPE l=arithmetics r=arithmetics) { $value = l | r; } |^(CARET l=arithmetics r=arithmetics) { $value = l ^ r; } |^(AMP l=arithmetics r=arithmetics) { $value = l & r; } diff --git a/scripts/binary_arithmetic.bash b/scripts/binary_arithmetic.bash index 330d07b..577ddbc 100644 --- a/scripts/binary_arithmetic.bash +++ b/scripts/binary_arithmetic.bash @@ -63,3 +63,5 @@ FOO057="$((${FOO056}++))" FOO058="$((${FOO056}+=10))" ARRAY=(1 2 3 4 5) FOO059="$((100**0))" +FOO060="$((FOO059||FOO059++))" +FOO061="$((0&&FOO059++))" diff --git a/scripts/binary_arithmetic.bash.result b/scripts/binary_arithmetic.bash.result index de065d6..926b23a 100644 --- a/scripts/binary_arithmetic.bash.result +++ b/scripts/binary_arithmetic.bash.result @@ -58,5 +58,7 @@ FOO056=value FOO057=100 FOO058=111 FOO059=1 +FOO060=1 +FOO061=0 PARTIAL=5 value=111 diff --git a/scripts/command_execution.bash b/scripts/command_execution.bash index 2df1b0d..d485d57 100644 --- a/scripts/command_execution.bash +++ b/scripts/command_execution.bash @@ -55,3 +55,4 @@ shopt -s extglob shopt -p printf "%s %s\n" abc def printf "%s %s\n" $FOO001, def +((FOO010=1)) diff --git a/scripts/command_execution.bash.result b/scripts/command_execution.bash.result index 3165843..280798b 100644 --- a/scripts/command_execution.bash.result +++ b/scripts/command_execution.bash.result @@ -63,3 +63,4 @@ FOO004=abc FOO005=1 2 3 FOO008=abc def ghi FOO009=10 +FOO010=1 diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp index c3b63d8..45cec7c 100644 --- a/src/core/bash_ast.cpp +++ b/src/core/bash_ast.cpp @@ -112,7 +112,7 @@ namespace } } -std::string bash_ast::get_tokens(std::function<std::string(ANTLR3_UINT32)> token_map) +std::string bash_ast::get_parser_tokens(std::function<std::string(ANTLR3_UINT32)> token_map) { std::stringstream result; int line_counter = 1; @@ -147,6 +147,26 @@ std::string bash_ast::get_tokens(std::function<std::string(ANTLR3_UINT32)> token print_line_counter(result, token, line_counter, tokenName == "CONTINUE_LINE"? 1 : 0); } } + return result.str(); +} + +std::string bash_ast::get_walker_tokens(std::function<std::string(ANTLR3_UINT32)> token_map) +{ + std::stringstream result; + pANTLR3_INT_STREAM istream = nodes->tnstream->istream; + auto istream_size = istream->size(istream); + + for(ANTLR3_UINT32 i = 1; i <= istream_size; ++i) + { + ANTLR3_UINT32 token = istream->_LA(istream, boost::numeric_cast<ANTLR3_INT32>(i)); + if(token == 2) + result << "DOWN "; + else if(token == 3) + result << "UP "; + else + result << token_map(istream->_LA(istream, boost::numeric_cast<ANTLR3_INT32>(i))) << " "; + } + result << std::endl; return result.str(); } diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h index 63e35d1..ae6bb0f 100644 --- a/src/core/bash_ast.h +++ b/src/core/bash_ast.h @@ -105,7 +105,9 @@ public: std::string get_string_tree(); - std::string get_tokens(std::function<std::string(ANTLR3_UINT32)>); + std::string get_parser_tokens(std::function<std::string(ANTLR3_UINT32)>); + + std::string get_walker_tokens(std::function<std::string(ANTLR3_UINT32)>); }; #endif diff --git a/test/ast_printer_test.sh b/test/ast_printer_test.sh index e0c930f..376b339 100755 --- a/test/ast_printer_test.sh +++ b/test/ast_printer_test.sh @@ -10,6 +10,10 @@ error+=$? | diff -u $srcdir/bashast/features_script/features.sh.tokens - error+=$? +./ast_printer -w libbashWalker.tokens -f $srcdir/bashast/features_script/features.sh\ + | diff -u $srcdir/bashast/features_script/features.sh.walker.tokens - +error+=$? + ./ast_printer -f $srcdir/bashast/features_script/illegal_script.sh 2 > /dev/null if [[ $? == 0 ]] then diff --git a/utils/ast_printer.cpp b/utils/ast_printer.cpp index 9c4bc3d..4921fa8 100644 --- a/utils/ast_printer.cpp +++ b/utils/ast_printer.cpp @@ -84,9 +84,9 @@ static bool build_token_map(std::unordered_map<ANTLR3_INT32, std::string>& token return qi::parse(first, last, line % qi::eol >> qi::eol, token_map) && first == last; } -static void print_token(std::istream& input, - const std::string& token_path, - bool silent) +static void print_parser_token(std::istream& input, + const std::string& token_path, + bool silent) { if(silent) return; @@ -95,9 +95,28 @@ static void print_token(std::istream& input, std::unordered_map<ANTLR3_INT32, std::string> token_map; if(build_token_map(token_map, token_path)) - std::cout << ast.get_tokens(std::bind(&token_mapper, - token_map, - std::placeholders::_1)) + std::cout << ast.get_parser_tokens(std::bind(&token_mapper, + token_map, + std::placeholders::_1)) + << std::endl; + else + std::cerr << "Building token map failed" << std::endl; +} + +static void print_walker_token(std::istream& input, + const std::string& token_path, + bool silent) +{ + if(silent) + return; + + bash_ast ast(input); + std::unordered_map<ANTLR3_INT32, std::string> token_map; + + if(build_token_map(token_map, token_path)) + std::cout << ast.get_walker_tokens(std::bind(&token_mapper, + token_map, + std::placeholders::_1)) << std::endl; else std::cerr << "Building token map failed" << std::endl; @@ -144,6 +163,8 @@ int main(int argc, char** argv) ("dot,d", "print graphviz doc file instead of tree string if -s is not specified") ("token,t", po::value<std::string>(), "Print all tokens instead of AST. " "The argument is the path to libbash.tokens") + ("walker-token,w", po::value<std::string>(), "Print all tokens received by the walker. " + "The argument is the path to libbashWalker.tokens") ("name,n", "When using files as input scripts, print out file names") ("silent,s", "do not print any AST") ; @@ -160,10 +181,15 @@ int main(int argc, char** argv) std::function<void(std::istream&)> printer; if(vm.count("token")) - printer = std::bind(&print_token, + printer = std::bind(&print_parser_token, std::placeholders::_1, vm["token"].as<std::string>(), vm.count("silent")); + else if(vm.count("walker-token")) + printer = std::bind(&print_walker_token, + std::placeholders::_1, + vm["walker-token"].as<std::string>(), + vm.count("silent")); else printer = std::bind(&print_ast, std::placeholders::_1, |