1 |
commit: 167e235cabb2528bc53e9d975053018c6b53fc04 |
2 |
Author: Petteri Räty <petsku <AT> petteriraty <DOT> eu> |
3 |
AuthorDate: Fri Apr 8 18:00:17 2011 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Apr 9 06:13:53 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=167e235c |
7 |
|
8 |
Improve support for arithmetic expressions |
9 |
|
10 |
Things like double negation $((!!a)) were not supported. Fixing this |
11 |
resulted in bubbled changes elsewhere. The main change is that we have |
12 |
less specialized tokens so that we don't end up with special tokens in |
13 |
wrong contexts. |
14 |
|
15 |
--- |
16 |
bashast/bashast.g | 44 +++++++++++++++++++---------------- |
17 |
bashast/gunit/arith_main.gunit | 22 +++++++++-------- |
18 |
bashast/gunit/compound.gunit | 6 ++-- |
19 |
bashast/gunit/cond_main.gunit | 8 +++--- |
20 |
bashast/gunit/continued_lines.gunit | 2 +- |
21 |
bashast/gunit/fname.gunit | 6 ++-- |
22 |
bashast/gunit/list.gunit | 2 +- |
23 |
bashast/gunit/simp_command.gunit | 2 +- |
24 |
8 files changed, 49 insertions(+), 43 deletions(-) |
25 |
|
26 |
diff --git a/bashast/bashast.g b/bashast/bashast.g |
27 |
index 2b4e713..bf07b7f 100644 |
28 |
--- a/bashast/bashast.g |
29 |
+++ b/bashast/bashast.g |
30 |
@@ -98,7 +98,7 @@ pipeline |
31 |
| BLANK!* time? (BANG BLANK!+)? command^ (BLANK!* PIPE^ BLANK!* command)*; |
32 |
time : TIME^ BLANK!+ time_posix?; |
33 |
time_posix |
34 |
- : '-p' BLANK!+; |
35 |
+ : TIME_POSIX BLANK!+; |
36 |
//The structure of a command in bash |
37 |
command |
38 |
: EXPORT^ var_def+ |
39 |
@@ -286,7 +286,7 @@ cond_primary |
40 |
keyword_cond_binary |
41 |
: cond_part BLANK!* binary_str_op_keyword^ BLANK!? cond_part; |
42 |
keyword_cond_unary |
43 |
- : UOP^ BLANK!+ cond_part; |
44 |
+ : uop^ BLANK!+ cond_part; |
45 |
builtin_cond_primary |
46 |
: LPAREN! BLANK!* builtin_cond BLANK!* RPAREN! |
47 |
| builtin_cond_binary |
48 |
@@ -295,7 +295,7 @@ builtin_cond_primary |
49 |
builtin_cond_binary |
50 |
: cond_part BLANK!* binary_string_op_builtin^ BLANK!? cond_part; |
51 |
builtin_cond_unary |
52 |
- : UOP^ BLANK!+ cond_part; |
53 |
+ : uop^ BLANK!+ cond_part; |
54 |
keyword_cond |
55 |
: (negate_primary|cond_primary) (BLANK!* (LOGICOR^|LOGICAND^) BLANK!* keyword_cond)?; |
56 |
builtin_cond |
57 |
@@ -305,20 +305,22 @@ negate_primary |
58 |
negate_builtin_primary |
59 |
: BANG BLANK+ builtin_cond_primary -> ^(NEGATION builtin_cond_primary); |
60 |
binary_str_op_keyword |
61 |
- : BOP |
62 |
+ : bop |
63 |
| EQUALS EQUALS -> OP["=="] |
64 |
| EQUALS |
65 |
| BANG EQUALS -> OP["!="] |
66 |
| LESS_THAN |
67 |
| GREATER_THAN; |
68 |
binary_string_op_builtin |
69 |
- : BOP |
70 |
+ : bop |
71 |
| EQUALS |
72 |
| BANG EQUALS -> OP["!="] |
73 |
| ESC_LT |
74 |
| ESC_GT; |
75 |
+bop : MINUS! NAME^; |
76 |
unary_cond |
77 |
- : UOP^ BLANK! cond_part; |
78 |
+ : uop^ BLANK! cond_part; |
79 |
+uop : MINUS! LETTER; |
80 |
//Allowable parts of conditions |
81 |
cond_part: brace_expansion |
82 |
| var_ref |
83 |
@@ -363,7 +365,11 @@ ns_str_part |
84 |
//Parts of strings, no slashes, no reserved words |
85 |
ns_str_part_no_res |
86 |
: num |
87 |
- | name|OTHER|EQUALS|PCT|PCTPCT|MINUS|DOT|DOTDOT|COLON|BOP|UOP|TEST_EXPR|'_'|TILDE|INC|DEC|MUL_ASSIGN|DIVIDE_ASSIGN|MOD_ASSIGN|PLUS_ASSIGN|MINUS_ASSIGN|LSHIFT_ASSIGN|RSHIFT_ASSIGN|AND_ASSIGN|XOR_ASSIGN|OR_ASSIGN|ESC_CHAR|CARET; |
88 |
+ | name |
89 |
+ |OTHER|EQUALS|PCT|PCTPCT|MINUS|DOT|DOTDOT|COLON|TEST_EXPR|'_' |
90 |
+ |TILDE|MUL_ASSIGN|DIVIDE_ASSIGN|MOD_ASSIGN|PLUS_ASSIGN|MINUS_ASSIGN |
91 |
+ |TIME_POSIX|LSHIFT_ASSIGN|RSHIFT_ASSIGN|AND_ASSIGN|XOR_ASSIGN |
92 |
+ |OR_ASSIGN|ESC_CHAR|CARET; |
93 |
//strings with no slashes, used in certain variable expansions |
94 |
ns_str : ns_str_part* -> ^(STRING ns_str_part*); |
95 |
//Generic strings/filenames. |
96 |
@@ -452,20 +458,19 @@ primary : num |
97 |
| name -> ^(VAR_REF name) |
98 |
| LPAREN! (arithmetics) RPAREN!; |
99 |
post_inc_dec |
100 |
- : name BLANK?INC -> ^(POST_INCR name) |
101 |
- | name BLANK?DEC -> ^(POST_DECR name); |
102 |
+ : primary BLANK? PLUS PLUS -> ^(POST_INCR primary) |
103 |
+ | primary BLANK? MINUS MINUS -> ^(POST_DECR primary); |
104 |
pre_inc_dec |
105 |
- : INC BLANK?name -> ^(PRE_INCR name) |
106 |
- | DEC BLANK?name -> ^(PRE_DECR name); |
107 |
+ : PLUS PLUS BLANK? primary -> ^(PRE_INCR primary) |
108 |
+ | MINUS MINUS BLANK? primary -> ^(PRE_DECR primary); |
109 |
unary : post_inc_dec |
110 |
| pre_inc_dec |
111 |
| primary |
112 |
- | PLUS primary -> ^(PLUS_SIGN primary) |
113 |
- | MINUS primary -> ^(MINUS_SIGN primary); |
114 |
-negation |
115 |
- : (BANG^BLANK!?|TILDE^BLANK!?)?unary; |
116 |
+ | PLUS unary -> ^(PLUS_SIGN unary) |
117 |
+ | MINUS unary -> ^(MINUS_SIGN unary) |
118 |
+ | (TILDE|BANG)^ unary; |
119 |
exponential |
120 |
- : negation (BLANK!* EXP^ BLANK!* negation)* ; |
121 |
+ : unary (BLANK!* EXP^ BLANK!* unary)* ; |
122 |
times_division_modulus |
123 |
: exponential (BLANK!* (TIMES^|SLASH^|PCT^) BLANK!* exponential)*; |
124 |
addsub : times_division_modulus (BLANK!* (PLUS^|MINUS^)BLANK!* times_division_modulus)*; |
125 |
@@ -540,8 +545,6 @@ TIMES : '*'; |
126 |
EQUALS : '='; |
127 |
MINUS : '-'; |
128 |
PLUS : '+'; |
129 |
-INC : '++'; |
130 |
-DEC : '--'; |
131 |
EXP : '**'; |
132 |
AMP : '&'; |
133 |
LEQ : '<='; |
134 |
@@ -600,8 +603,6 @@ TEST_EXPR : 'test'; |
135 |
LOGICAND |
136 |
: '&&'; |
137 |
LOGICOR : '||'; |
138 |
-BOP : MINUS LETTER LETTER; |
139 |
-UOP : MINUS LETTER; |
140 |
//Some builtins |
141 |
EXPORT : 'export'; |
142 |
//Tokens for strings |
143 |
@@ -613,6 +614,9 @@ ESC_LPAREN |
144 |
: '\\' LPAREN; |
145 |
ESC_LT : '\\''<'; |
146 |
ESC_GT : '\\''>'; |
147 |
+//For pipeline |
148 |
+TIME_POSIX |
149 |
+ : '-p'; |
150 |
//Handle ANSI C escaped characters: escaped octal, escaped hex, escaped ctrl+ chars, then all others |
151 |
ESC_CHAR: '\\' (('0'..'7')('0'..'7')('0'..'7')?|'x'('0'..'9'|'a'..'f'|'A'..'F')('0'..'9'|'a'..'f'|'A'..'F')?|'c'.|.); |
152 |
NAME : (LETTER|'_')(ALPHANUM|'_')+; |
153 |
|
154 |
diff --git a/bashast/gunit/arith_main.gunit b/bashast/gunit/arith_main.gunit |
155 |
index be91c42..9010822 100644 |
156 |
--- a/bashast/gunit/arith_main.gunit |
157 |
+++ b/bashast/gunit/arith_main.gunit |
158 |
@@ -25,24 +25,26 @@ primary: |
159 |
"3" -> "3" |
160 |
|
161 |
post_inc_dec: |
162 |
-"b--" -> (POST_DECR b) |
163 |
-"i++" -> (POST_INCR i) |
164 |
+"b--" -> (POST_DECR (VAR_REF b)) |
165 |
+"i++" -> (POST_INCR (VAR_REF i)) |
166 |
|
167 |
pre_inc_dec: |
168 |
-"++i" -> (PRE_INCR i) |
169 |
-"--b" -> (PRE_DECR b) |
170 |
+"++i" -> (PRE_INCR (VAR_REF i)) |
171 |
+"--b" -> (PRE_DECR (VAR_REF b)) |
172 |
|
173 |
unary: |
174 |
"6" -> "6" |
175 |
"+9" -> (PLUS_SIGN 9) |
176 |
"-15" -> (MINUS_SIGN 15) |
177 |
-"++ z" -> (PRE_INCR z) |
178 |
-"f--" -> (POST_DECR f) |
179 |
- |
180 |
-negation: |
181 |
-"8" -> "8" |
182 |
+"++ z" -> (PRE_INCR (VAR_REF z)) |
183 |
+"f--" -> (POST_DECR (VAR_REF f)) |
184 |
"~8" -> (~ 8) |
185 |
"!8" -> (! 8) |
186 |
+"!!8" -> (! (! 8)) |
187 |
+"--8" -> (PRE_DECR 8) |
188 |
+"+++${a}" -> (PLUS_SIGN (PRE_INCR (VAR_REF a))) |
189 |
+"++++${a}" -> (PLUS_SIGN (PLUS_SIGN (PRE_INCR (VAR_REF a)))) |
190 |
+"+-++${a}" -> (PLUS_SIGN (MINUS_SIGN (PRE_INCR (VAR_REF a)))) |
191 |
|
192 |
exponential: |
193 |
"8" -> "8" |
194 |
@@ -120,5 +122,5 @@ arithmetics: |
195 |
|
196 |
start: |
197 |
"echo $(( 3 + 2 ))" -> (LIST (COMMAND (STRING echo) (STRING (ARITHMETIC_EXPRESSION (+ 3 2))))) |
198 |
-"echo $((++i))" -> (LIST (COMMAND (STRING echo) (STRING (ARITHMETIC_EXPRESSION (PRE_INCR i))))) |
199 |
+"echo $((++i))" -> (LIST (COMMAND (STRING echo) (STRING (ARITHMETIC_EXPRESSION (PRE_INCR (VAR_REF i)))))) |
200 |
"echo \"The solution is: $(( 3+2 ))\""-> (LIST (COMMAND (STRING echo) (STRING (DOUBLE_QUOTED_STRING The solution is : (ARITHMETIC_EXPRESSION (+ 3 2)))))) |
201 |
|
202 |
diff --git a/bashast/gunit/compound.gunit b/bashast/gunit/compound.gunit |
203 |
index 2e0c795..b8e8ef6 100644 |
204 |
--- a/bashast/gunit/compound.gunit |
205 |
+++ b/bashast/gunit/compound.gunit |
206 |
@@ -19,12 +19,12 @@ |
207 |
gunit bashast; |
208 |
|
209 |
cond_comparison: |
210 |
-"[[ -a this/is.afile ]]" -> (COMPOUND_COND (KEYWORD_TEST (-a (STRING this / is . afile)))) |
211 |
+"[[ -a this/is.afile ]]" -> (COMPOUND_COND (KEYWORD_TEST (a (STRING this / is . afile)))) |
212 |
"[[ -a this/is.afile]]" FAIL |
213 |
"[[-a this/is.afile ]]" FAIL |
214 |
"[[ |
215 |
--a this/is.afile ]]" -> (COMPOUND_COND (KEYWORD_TEST (-a (STRING this / is . afile)))) |
216 |
-"test ! -a this/is.afile" -> (COMPOUND_COND (BUILTIN_TEST (NEGATION (-a (STRING this / is . afile))))) |
217 |
+-a this/is.afile ]]" -> (COMPOUND_COND (KEYWORD_TEST (a (STRING this / is . afile)))) |
218 |
+"test ! -a this/is.afile" -> (COMPOUND_COND (BUILTIN_TEST (NEGATION (a (STRING this / is . afile))))) |
219 |
"[[ asdf > qwert ]]" -> (COMPOUND_COND (KEYWORD_TEST (> (STRING asdf) (STRING qwert)))) |
220 |
"[ asdf \> qwert ]" -> (COMPOUND_COND (BUILTIN_TEST (\> (STRING asdf) (STRING qwert)))) |
221 |
|
222 |
|
223 |
diff --git a/bashast/gunit/cond_main.gunit b/bashast/gunit/cond_main.gunit |
224 |
index 91eb883..b40322d 100644 |
225 |
--- a/bashast/gunit/cond_main.gunit |
226 |
+++ b/bashast/gunit/cond_main.gunit |
227 |
@@ -19,9 +19,9 @@ |
228 |
gunit bashast; |
229 |
|
230 |
cond_expr: |
231 |
-"[[ -a this/is.afile ]]" -> (KEYWORD_TEST (-a (STRING this / is . afile))) |
232 |
-"[ -n \"yar53\" ]" -> (BUILTIN_TEST (-n (STRING (DOUBLE_QUOTED_STRING yar53)))) |
233 |
-"test 5 -eq 6" -> (BUILTIN_TEST (-eq 5 6)) |
234 |
-"[[ \"asdf\" != \"boo\" && -a filename ]]" -> (KEYWORD_TEST (&& (!= (STRING (DOUBLE_QUOTED_STRING asdf)) (STRING (DOUBLE_QUOTED_STRING boo))) (-a (STRING filename)))) |
235 |
+"[[ -a this/is.afile ]]" -> (KEYWORD_TEST (a (STRING this / is . afile))) |
236 |
+"[ -n \"yar53\" ]" -> (BUILTIN_TEST (n (STRING (DOUBLE_QUOTED_STRING yar53)))) |
237 |
+"test 5 -eq 6" -> (BUILTIN_TEST (eq 5 6)) |
238 |
+"[[ \"asdf\" != \"boo\" && -a filename ]]" -> (KEYWORD_TEST (&& (!= (STRING (DOUBLE_QUOTED_STRING asdf)) (STRING (DOUBLE_QUOTED_STRING boo))) (a (STRING filename)))) |
239 |
"[[ true ]]" -> (KEYWORD_TEST (STRING true)) |
240 |
"[[ true && (false || three) ]]" -> (KEYWORD_TEST (&& (STRING true) (|| (STRING false) (STRING three)))) |
241 |
|
242 |
diff --git a/bashast/gunit/continued_lines.gunit b/bashast/gunit/continued_lines.gunit |
243 |
index debbe1f..96f6ee4 100644 |
244 |
--- a/bashast/gunit/continued_lines.gunit |
245 |
+++ b/bashast/gunit/continued_lines.gunit |
246 |
@@ -26,4 +26,4 @@ o Hello\ |
247 |
|
248 |
"sed -i \ |
249 |
-e 's/three/\ |
250 |
- four/'" -> (LIST (COMMAND (STRING sed) (STRING -i) (STRING -e) (STRING (SINGLE_QUOTED_STRING s / three / four /)))) |
251 |
+ four/'" -> (LIST (COMMAND (STRING sed) (STRING - i) (STRING - e) (STRING (SINGLE_QUOTED_STRING s / three / four /)))) |
252 |
|
253 |
diff --git a/bashast/gunit/fname.gunit b/bashast/gunit/fname.gunit |
254 |
index 4596f23..0272c37 100644 |
255 |
--- a/bashast/gunit/fname.gunit |
256 |
+++ b/bashast/gunit/fname.gunit |
257 |
@@ -49,9 +49,9 @@ fname: |
258 |
"tab\\ttab" -> "(STRING tab \\\t tab)" |
259 |
"abc[def]" -> (STRING abc (MATCH_PATTERN def)) |
260 |
"a[]" -> (STRING a [ ]) |
261 |
-"ab[d-h]" -> (STRING ab (MATCH_PATTERN d -h)) |
262 |
-"ab[!d-h]" -> (STRING ab (MATCH_ANY_EXCEPT d -h)) |
263 |
-"ab[^d-h]" -> (STRING ab (MATCH_ANY_EXCEPT d -h)) |
264 |
+"ab[d-h]" -> (STRING ab (MATCH_PATTERN d - h)) |
265 |
+"ab[!d-h]" -> (STRING ab (MATCH_ANY_EXCEPT d - h)) |
266 |
+"ab[^d-h]" -> (STRING ab (MATCH_ANY_EXCEPT d - h)) |
267 |
"ab[]c]" -> (STRING ab (MATCH_PATTERN ] c)) |
268 |
"ab[:alpha:]" -> (STRING ab (MATCH_PATTERN : alpha :)) |
269 |
"ab[=c=]" -> (STRING ab (MATCH_PATTERN = c =)) |
270 |
|
271 |
diff --git a/bashast/gunit/list.gunit b/bashast/gunit/list.gunit |
272 |
index 04b3243..f21f014 100644 |
273 |
--- a/bashast/gunit/list.gunit |
274 |
+++ b/bashast/gunit/list.gunit |
275 |
@@ -22,7 +22,7 @@ list: |
276 |
"make" -> (LIST (COMMAND (STRING make))) |
277 |
"make && make modules_install;" -> (LIST (&& (COMMAND (STRING make)) (COMMAND (STRING make) (STRING modules_install)))) |
278 |
"make && make modules_install &" -> (LIST (&& (COMMAND (STRING make)) (COMMAND (STRING make) (STRING modules_install)))) |
279 |
-"cd /usr/bin; ls -al |grep more&& cp ./less ./more" -> (LIST (COMMAND (STRING cd) (STRING / usr / bin)) (&& (| (COMMAND (STRING ls) (STRING -al)) (COMMAND (STRING grep) (STRING more))) (COMMAND (STRING cp) (STRING . / less) (STRING . / more)))) |
280 |
+"cd /usr/bin; ls -al |grep more&& cp ./less ./more" -> (LIST (COMMAND (STRING cd) (STRING / usr / bin)) (&& (| (COMMAND (STRING ls) (STRING - al)) (COMMAND (STRING grep) (STRING more))) (COMMAND (STRING cp) (STRING . / less) (STRING . / more)))) |
281 |
"mkdir test |
282 |
cd test |
283 |
cp ../asdf.tar.gz . |
284 |
|
285 |
diff --git a/bashast/gunit/simp_command.gunit b/bashast/gunit/simp_command.gunit |
286 |
index 6f2c2a8..cd847a8 100644 |
287 |
--- a/bashast/gunit/simp_command.gunit |
288 |
+++ b/bashast/gunit/simp_command.gunit |
289 |
@@ -24,7 +24,7 @@ simple_command: |
290 |
"asdf=5 cat out.log > result" -> (COMMAND (STRING cat) (STRING out . log) (= asdf 5) (REDIR > (STRING result))) |
291 |
"cat results.log > asdf 2> /dev/null" -> (COMMAND (STRING cat) (STRING results . log) (REDIR > (STRING asdf)) (REDIR 2 > (STRING / dev / null))) |
292 |
"i=3 g=4 h=18 grep asdf" -> (COMMAND (STRING grep) (STRING asdf) (= i 3) (= g 4) (= h 18)) |
293 |
-"./configure --prefix=/usr/local" -> (COMMAND (STRING . / configure) (STRING -- prefix = / usr / local)) |
294 |
+"./configure --prefix=/usr/local" -> (COMMAND (STRING . / configure) (STRING - -p refix = / usr / local)) |
295 |
"[[while" -> (COMMAND (STRING [ [ while)) |
296 |
"./foobär" -> (COMMAND (STRING . / foob ä r)) |
297 |
"cat ~/Documents/todo.txt" -> (COMMAND (STRING cat) (STRING ~ / Documents / todo . txt)) |