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

Reply via email to