On Tue, May 21, 2024 at 1:57 PM Natanael Copa <[email protected]> wrote:
>
> On Tue, 21 May 2024 08:46:46 +0200
> Natanael Copa <[email protected]> wrote:
>
> > > Current git master awk is also broken.
> >
> > A reproducer:
> >
> > busybox awk 'BEGIN { a = 0 ? "yes": "no"; print a}'
> >
> > Prints 0 instead of "no".
> >
> > Looks like awk treats it as: (a = 0) ? "yes": "no"
>
>
> I think commit 0256e00a9d07 (awk: fix precedence of = relative to ==)
> may be wrong? At least it is different from other awk implementations:
>
> ncopa-desktop:~/src/busybox/build (master)$ ./busybox awk 'BEGIN { print
> v=3==3; print v}'
> 1
> 3
> ncopa-desktop:~/src/busybox/build (master)$ gawk 'BEGIN { print v=3==3; print
> v}'
> 1
> 1
> ncopa-desktop:~/src/busybox/build (master)$ mawk 'BEGIN { print v=3==3; print
> v}'
> 1
> 1
okay... the above means v=(3==3) but ...
$ gawk 'BEGIN { print 3==v=3; print v}'
1
3
Looks like it did 3==(v=3) in this case??
> ncopa-desktop:~/src/busybox/build (master)$ nawk 'BEGIN { print v=3==3; print
> v}'
> nawk: syntax error at source line 1
> context is
> BEGIN { print >>> v=3== <<<
> nawk: illegal statement at source line 1
> nawk: illegal statement at source line 1
> ncopa-desktop:~/src/busybox/build (master)$ nawk 'BEGIN { print (v=3==3);
> print v}'
> 1
> 1
> ncopa-desktop:~/src/busybox/build (master)$ ./busybox awk 'BEGIN { print
> (v=3==3); print v}'
> 1
> 3
>
> And on FreeBSD:
>
> ncopa@fbsd13:~ $ awk 'BEGIN { print v=3==3; print v}'
> awk: syntax error at source line 1
> context is
> BEGIN { print >>> v=3== <<<
> awk: illegal statement at source line 1
>
>
> The awk.tests claims:
> > "awk = has higher precedence than == (despite what gawk manpage claims)"
>
> Denys, from where did you get that "= has higher precedence than =="?
From this (gawk results shown, and bbox currently mimics it):
$ echo "foo" | awk '$1==$1="foo" {print $1}'
foo
$ echo "bar" | awk '$1==$1="foo" {print $1}'
$
(Can you try it on those awk implementations?)
From the above, it means that $1==$1="foo" is parsed as $1==($1="foo"),
not as ($1==$1)="foo" - the latter would be a syntax error,
attempt to assign a value to something which isn't a variable.
If I roll back the precedence change:
- OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74),
OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-',
- OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/',
OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&',
- OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-',
OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&',
+ OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(38),
OC_REPLACE|NV|P(38)|'+', OC_REPLACE|NV|P(38)|'-',
+ OC_REPLACE|NV|P(38)|'*', OC_REPLACE|NV|P(38)|'/',
OC_REPLACE|NV|P(38)|'%', OC_REPLACE|NV|P(38)|'&',
+ OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-',
OC_REPLACE|NV|P(38)|'&', OC_BINARY|NV|P(15)|'&',
in the above example awk will bomb out on this check:
/* Prevent:
* awk 'BEGIN { "qwe" = 1 }'
* awk 'BEGIN { 7 *= 7 }'
* awk 'BEGIN { length("qwe") = 1 }'
* awk 'BEGIN { (1+1) += 3 }'
*/
/* Assignment? (including *= and friends) */
if (((t_info & OPCLSMASK) == OC_MOVE)
|| ((t_info & OPCLSMASK) == OC_REPLACE)
) {
debug_printf_parse("%s:
MOVE/REPLACE vn->info:%08x\n", __func__, vn->info);
/* Left side is a (variable or
array element)
* or function argument
* or $FIELD ?
*/
if ((vn->info & OPCLSMASK) != OC_VAR
&& (vn->info & OPCLSMASK) != OC_FNARG
&& (vn->info & OPCLSMASK) != OC_FIELD
) {
syntax_error(EMSG_UNEXP_TOKEN); <======= HERE
vn->info is 0x27031405, that is, opcode 14: OC_COMPARE, the "==" operation.
"Assigning" to the result of comparison does not make sense.
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox