[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Question about arithmetic expression grammar
From: |
Stephane Chazelas |
Subject: |
Re: Question about arithmetic expression grammar |
Date: |
Mon, 10 Oct 2016 14:57:23 +0100 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
2016-10-08 17:33:00 +0200, Conrad Hoffmann:
[...]
> $ TEST=5; echo $((--TEST+++3)) # outputs 7
>
> However, due to the documented operator precedence, I would have
> expected that expression to be equal to:
>
> $ TEST=5; echo $((--(TEST++)+3)) # outputs 8
>
> Instead, though, it seems to be equal this one:
>
> $ TEST=5; echo $(((--TEST)+++3)) # outputs 7
>
> So my qestions are:
>
> Is this a bug? Or is this something that can't be resolved due
> ambiguities in the grammar? Or what's going on here at all?
[...]
--, ++ are optional in POSIX. That means you can't use those
operators in POSIX scripts and that if you need to combine two
unary - or + or a binary - with a unary -, you need to use
spaces or paren:
$((1--1)) # unspecified
$((--1)) # unspecified
$((--var)) # unspecified
$((1 - -1)) # OK
$((- -1)) # OK
$((1-(-1))) # OK
$((-(-1))) # OK
Now, if we look at the C spec, the way +++ is parsed is down to
tokenisation that will also go for the longest operator first.
There --test+++3 would be tokenised as -- test ++ + 3 which
would lead to a syntax error as test++ isn't an lvalue.
bash works differently.
>From what I understand from past discussions on the subject here
bash doesn't treat it as a syntax error and tries instead to tokenise
those incorrect ++/-- into multiple + or - operators if possible.
So here, --TEST+++3 is:
--TEST + +(+3)
And --(TEST++)+3
would be: -(-(TEST++))+3
--
Stephane