[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] pretty-print eats parentheses
From: |
Aharon Robbins |
Subject: |
Re: [bug-gawk] pretty-print eats parentheses |
Date: |
Thu, 30 Oct 2014 21:38:17 +0200 |
User-agent: |
Heirloom mailx 12.5 6/20/10 |
Hi. Thanks for the reports. Fix below. This was interesting.
First, our test file:
$ cat x.awk
BEGIN {
x = 3
print -(-x)
Q = "|"
print -3 Q (-4)
print -3 Q (-4) (-5)
}
Now a run with released gawk:
$ gawk-4.1.1 -o/dev/stdout -f x.awk
3
-3|-4
-3|-4-5
# gawk profile, created Thu Oct 30 21:35:24 2014
# BEGIN block(s)
BEGIN {
x = 3
print --x
Q = "|"
print -3 Q -4
print -3 Q -4 -5
}
Interestingly, 3.1.8 got it partially right:
$ gawk-3.1.8 --profile=/dev/stdout -f x.awk
3
-3|-4
-3|-4-5
# gawk profile, created Thu Oct 30 21:36:10 2014
# BEGIN block(s)
BEGIN {
x = 3
print -( -x)
Q = "|"
print (-3 Q -4)
print (-3 Q -4 -5)
}
And now, after patching:
$ ./gawk -o/dev/stdout -f x.awk
3
-3|-4
-3|-4-5
# gawk profile, created Thu Oct 30 21:36:30 2014
# BEGIN rule(s)
BEGIN {
x = 3
print -(-x)
Q = "|"
print -3 Q (-4)
print -3 Q (-4) (-5)
}
Here is the fix. It will be in the git repo shortly.
Arnold
-------------------------
diff --git a/ChangeLog b/ChangeLog
index 8f4657a..a74dadd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,15 @@
* configure: Regenerated after fix to m4/readline.m4.
+ Unrelated; fixes to profiling. Thanks to Hermann Peifer and
+ Manuel Collado for pointing out problems:
+
+ * profile.c (pprint): For Op_unary_minus, parenthesize -(-x)
+ correctly.
+ (prec_level): Get the levels right (checked the grammar).
+ (is_unary_minus): New function.
+ (pp_concat): Add checks for unary minus; needs to be parenthesized.
+
2014-10-29 Arnold D. Robbins <address@hidden>
* dfa.c: Sync with GNU grep. Again, again.
diff --git a/profile.c b/profile.c
index a5ed381..ed17e62 100644
--- a/profile.c
+++ b/profile.c
@@ -395,7 +395,8 @@ cleanup:
case Op_unary_minus:
case Op_not:
t1 = pp_pop();
- if (is_binary(t1->type))
+ if (is_binary(t1->type)
+ || (((OPCODE) t1->type) == pc->opcode && pc->opcode
== Op_unary_minus))
pp_parenthesize(t1);
/* optypes table (eval.c) includes space after ! */
@@ -1000,25 +1001,25 @@ prec_level(int type)
case Op_func_call:
case Op_K_delete_loop:
case Op_builtin:
- return 15;
+ return 16;
case Op_field_spec:
case Op_field_spec_lhs:
- return 14;
-
- case Op_exp:
- case Op_exp_i:
- return 13;
+ return 15;
case Op_preincrement:
case Op_predecrement:
case Op_postincrement:
case Op_postdecrement:
- return 12;
+ return 14;
+
+ case Op_exp:
+ case Op_exp_i:
+ return 13;
case Op_unary_minus:
case Op_not:
- return 11;
+ return 12;
case Op_times:
case Op_times_i:
@@ -1026,23 +1027,26 @@ prec_level(int type)
case Op_quotient_i:
case Op_mod:
case Op_mod_i:
- return 10;
+ return 11;
case Op_plus:
case Op_plus_i:
case Op_minus:
case Op_minus_i:
- return 9;
+ return 10;
case Op_concat:
case Op_assign_concat:
- return 8;
+ return 9;
case Op_equal:
case Op_notequal:
case Op_greater:
+ case Op_less:
case Op_leq:
case Op_geq:
+ return 8;
+
case Op_match:
case Op_nomatch:
return 7;
@@ -1051,7 +1055,6 @@ prec_level(int type)
case Op_K_getline_redir:
return 6;
- case Op_less:
case Op_in_array:
return 5;
@@ -1360,6 +1363,14 @@ pp_list(int nargs, const char *paren, const char *delim)
return str;
}
+/* is_unary_minus --- return true if string starts with unary minus */
+
+static bool
+is_unary_minus(const char *str)
+{
+ return str[0] == '-' && str[1] != '-';
+}
+
/* pp_concat --- handle concatenation and correct parenthesizing of
expressions */
static char *
@@ -1401,7 +1412,12 @@ pp_concat(int nargs)
pl_l = prec_level(pp_args[i]->type);
pl_r = prec_level(pp_args[i+1]->type);
- if (is_scalar(pp_args[i]->type) &&
is_scalar(pp_args[i+1]->type)) {
+ if (i >= 2 && is_unary_minus(r->pp_str)) {
+ *s++ = '(';
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ *s++ = ')';
+ } else if (is_scalar(pp_args[i]->type) &&
is_scalar(pp_args[i+1]->type)) {
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;
} else if (pl_l <= pl_r || is_scalar(pp_args[i+1]->type)) {
@@ -1423,7 +1439,7 @@ pp_concat(int nargs)
pl_l = prec_level(pp_args[nargs-1]->type);
pl_r = prec_level(pp_args[nargs]->type);
r = pp_args[nargs];
- if (pl_l >= pl_r && ! is_scalar(pp_args[nargs]->type)) {
+ if (is_unary_minus(r->pp_str) || ((pl_l >= pl_r && !
is_scalar(pp_args[nargs]->type)))) {
*s++ = '(';
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;