Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #20434 > unrolled thread

Operator precedence.

Started bysomenath <somenathpal@gmail.com>
First post2012-05-06 20:10 -0700
Last post2012-05-10 15:24 -0700
Articles 20 on this page of 43 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  Operator precedence. somenath <somenathpal@gmail.com> - 2012-05-06 20:10 -0700
    Re: Operator precedence. somenath <somenathpal@gmail.com> - 2012-05-06 20:23 -0700
    Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-06 23:57 -0400
    Re: Operator precedence. Kaz Kylheku <kaz@kylheku.com> - 2012-05-07 03:59 +0000
    Re: Operator precedence. pete <pfiland@mindspring.com> - 2012-05-07 05:48 -0400
      Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-07 07:52 -0400
        Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-07 13:18 +0100
          Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-07 09:08 -0400
            Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-07 14:36 +0100
              Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-07 13:29 -0400
        Re: Operator precedence. pete <pfiland@mindspring.com> - 2012-05-07 11:24 -0400
    Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-07 16:35 +0100
      Re: Operator precedence. jgk@panix.com (Joe keane) - 2012-05-10 19:05 +0000
        Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-10 20:35 +0100
          Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-11 09:25 -0400
            Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-11 16:42 +0100
              Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-11 12:28 -0400
                Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-11 18:42 +0100
                  Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-11 15:18 -0400
                    Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-11 22:52 +0100
                      Re: Operator precedence. James Kuyper <jameskuyper@verizon.net> - 2012-05-11 18:39 -0400
                  Re: Operator precedence. Ike Naar <ike@sverige.freeshell.org> - 2012-05-11 19:20 +0000
                    Re: Operator precedence. Ike Naar <ike@sverige.freeshell.org> - 2012-05-11 19:28 +0000
                      Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-11 22:28 +0100
                        Re: Operator precedence. Ike Naar <ike@sverige.freeshell.org> - 2012-05-11 21:45 +0000
                Re: Operator precedence. Keith Thompson <kst-u@mib.org> - 2012-05-12 12:11 -0700
              Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-11 17:37 +0100
          Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-11 16:24 +0100
            Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-11 20:14 +0100
              Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-11 20:56 +0100
                Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-11 22:21 +0100
                  Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-12 00:05 +0100
            Re: Operator precedence. jgk@panix.com (Joe keane) - 2012-05-11 22:46 +0000
              Re: Operator precedence. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-05-12 00:17 +0100
                Re: Operator precedence. jgk@panix.com (Joe keane) - 2012-05-12 19:35 +0000
                  Re: Operator precedence. "BartC" <bc@freeuk.com> - 2012-05-12 22:39 +0100
              Re: Operator precedence. Keith Thompson <kst-u@mib.org> - 2012-05-12 16:07 -0700
                Re: Operator precedence. jgk@panix.com (Joe keane) - 2012-05-13 19:08 +0000
                  Re: Operator precedence. Keith Thompson <kst-u@mib.org> - 2012-05-13 13:17 -0700
                    Re: Operator precedence. jgk@panix.com (Joe keane) - 2012-05-14 21:06 +0000
                      Re: Operator precedence. Keith Thompson <kst-u@mib.org> - 2012-05-14 20:42 -0700
                  Re: Operator precedence. Kaz Kylheku <kaz@kylheku.com> - 2012-05-13 23:20 +0000
        Re: Operator precedence. Keith Thompson <kst-u@mib.org> - 2012-05-10 15:24 -0700

Page 1 of 3  [1] 2 3  Next page →


#20434 — Operator precedence.

Fromsomenath <somenathpal@gmail.com>
Date2012-05-06 20:10 -0700
SubjectOperator precedence.
Message-ID<76630b90-04ab-4976-b1a0-76868d85ccf5@vy9g2000pbc.googlegroups.com>
Hi All,

While browsing through the old article in this group I have come
across  one article by Chrish Torek.
http://groups.google.com/group/gnu.gcc.help/browse_thread/thread/31750b84b212325/d97a0f655e96ce16?lnk=gst&q=compiler+munching+%2B++chrish+torek#d97a0f655e96ce16


In this article he said.

"Finally, let me say one last time that the Standard C grammar DOES
NOT use operator precedence.  (At most, one can say that the grammar
"implies" a precedence.  I believe the word "specifies" is too
strong, despite its appearance in a non-normative footnote."

So the  following expression

2+3*5;
is equal to 17.  For  human * has higher precedence than + so *
operator will be first operated on 3*5 and then the resultant will be
added to 2. So the result will be 2+(3*5) .

Then my question is how C compiler with out bothering about precedence
produce the same result as 2+(3*5).

I tried to explain myself the outcome of 2+3*5  the way Chris Torek
has explained the expression   -- - x  but I am not able to construes
how the precedence of * will be enforced by the C grammar with out
using operator precedence.

Regards,
Somenath

[toc] | [next] | [standalone]


#20435

Fromsomenath <somenathpal@gmail.com>
Date2012-05-06 20:23 -0700
Message-ID<d6425ec9-c597-485d-a2a2-d7791be41e69@t2g2000pbg.googlegroups.com>
In reply to#20434
On May 7, 8:10 am, somenath <somenath...@gmail.com> wrote:
> Hi All,
>
> While browsing through the old article in this group I have come
> across  one article by Chrish Torek.http://groups.google.com/group/gnu.gcc.help/browse_thread/thread/3175...
>

I apologize . This I did not found in CLC but in different group. But
as the article was for standard C I think the question will not be off
topic for CLC.

[toc] | [prev] | [next] | [standalone]


#20437

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-06 23:57 -0400
Message-ID<jo7h7t$ehv$1@dont-email.me>
In reply to#20434
On 05/06/2012 11:10 PM, somenath wrote:
> Hi All,
> 
> While browsing through the old article in this group I have come
> across  one article by Chrish Torek.
> http://groups.google.com/group/gnu.gcc.help/browse_thread/thread/31750b84b212325/d97a0f655e96ce16?lnk=gst&q=compiler+munching+%2B++chrish+torek#d97a0f655e96ce16
> 
> 
> In this article he said.
> 
> "Finally, let me say one last time that the Standard C grammar DOES
> NOT use operator precedence.  (At most, one can say that the grammar
> "implies" a precedence.  I believe the word "specifies" is too
> strong, despite its appearance in a non-normative footnote."
> 
> So the  following expression
> 
> 2+3*5;
> is equal to 17.  For  human * has higher precedence than + so *
> operator will be first operated on 3*5 and then the resultant will be
> added to 2. So the result will be 2+(3*5) .
> 
> Then my question is how C compiler with out bothering about precedence
> produce the same result as 2+(3*5).

Without going into the details, let me state that 2, 3, and 5 all
qualify as "cast-expressions".

The relevant grammar rules are:

multiplicative-expression:
	cast-expression
	multiplicative-expression * cast-expression

additive-expression:
	multiplicative-expression
	additive-expression + multiplicative-expression

The parse tree is as follows (monospaced font required):

	    2             +            3              *        5
     cast-expression      +      cast-expression      * cast-expression
     cast-expression      +(multiplicative-expression * cast-expression)
multiplicative-expression +          multiplicative-expression
  (additive-expression    +          multiplicative-expression)
                  additive-expression

These grammar rules encode the equivalent of operator precedence in the
fact that the grammar rules for a additive expression require
multiplicative expressions as operands, whereas multiplicative
expressions do not allow additive expressions as operators. If the C
grammar followed a similar pattern for all of the operators, it would be
equally accurate to describe it in terms of precedence or grammar rules.

However, the grammar rules for the conditional expressions do not allow
for a simple precedence-based interpretation:

conditional-expression:
        logical-OR-expression
        logical-OR-expression ? expression : conditional-express

Any kind of expression can occur between the ? and the :, which would
imply that conditional expressions have the lowest possible precedence.
However, neither the first nor the third operand of a conditional
expression can be an assignment expression or a comma expression, which
would imply that it has higher precedence than assignment operators or
the comma operator.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20438

FromKaz Kylheku <kaz@kylheku.com>
Date2012-05-07 03:59 +0000
Message-ID<20120506203524.309@kylheku.com>
In reply to#20434
On 2012-05-07, somenath <somenathpal@gmail.com> wrote:
> has explained the expression   -- - x  but I am not able to construes
> how the precedence of * will be enforced by the C grammar with out
> using operator precedence.

Like this example grammar:

expression := term 
           |  expression + term
           |  expression - term


term := factor
     |  term * factor
     |  term / factor


factor := ( expression )
        | number
        | identifier

No associativity or precedence is expressed directly by the grammar.

The precedence of * and / is implicity higher than that of + and -
because * and / occur only inside a term, and an expression is made
of terms separated by + or -. The rules are implicitly hierarchical.

Associativity is implicitly left to right because the rules are
left recursive. There is no ambiguity because we do not have ambiguous
rules like this:

   expression := expression + expression

but rather 

   expression := expression + term

So if you have this:

   1 + 2 + 3

the only way it can match the pattern "expression + term" is if "1 + 2"
is "expression" and "3" is "term". So it means that 3 is added to the
sum of 1 + 2.

[toc] | [prev] | [next] | [standalone]


#20443

Frompete <pfiland@mindspring.com>
Date2012-05-07 05:48 -0400
Message-ID<4FA79A67.5017@mindspring.com>
In reply to#20434
somenath wrote:
> 
> Hi All,
> 
> While browsing through the old article in this group I have come
> across  one article by Chrish Torek.
> http://groups.google.com/group/gnu.gcc.help/browse_thread/thread/31750b84b212325/d97a0f655e96ce16?lnk=gst&q=compiler+munching+%2B++chrish+torek#d97a0f655e96ce16
> 
> In this article he said.
> 
> "Finally, let me say one last time that the Standard C grammar DOES
> NOT use operator precedence.  (At most, one can say that the grammar
> "implies" a precedence.  I believe the word "specifies" is too
> strong, despite its appearance in a non-normative footnote."
> 
> So the  following expression
> 
> 2+3*5;
> is equal to 17.  For  human * has higher precedence than + so *
> operator will be first operated on 3*5 and then the resultant will be
> added to 2. So the result will be 2+(3*5) .
> 
> Then my question is how C compiler with out bothering about precedence
> produce the same result as 2+(3*5).
> 
> I tried to explain myself the outcome of 2+3*5  the way Chris Torek
> has explained the expression   -- - x  but I am not able to construes
> how the precedence of * will be enforced by the C grammar with out
> using operator precedence.

I can't do it either.
I use the precedence table in chapter 2 of K&R instead.

-- 
pete

[toc] | [prev] | [next] | [standalone]


#20449

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-07 07:52 -0400
Message-ID<jo8d19$bm5$1@dont-email.me>
In reply to#20443
On 05/07/2012 05:48 AM, pete wrote:
> somenath wrote:
...
>> I tried to explain myself the outcome of 2+3*5  the way Chris Torek
>> has explained the expression   -- - x  but I am not able to construes
>> how the precedence of * will be enforced by the C grammar with out
>> using operator precedence.
> 
> I can't do it either.
> I use the precedence table in chapter 2 of K&R instead.

What does that table say about the relative precedence of ||, ?:, =, and
the comma operator? Using that table and the corresponding information
about the associativity of the operators, how do you parse the two
following expressions:

	 a ||  b       ?  d , e  :  f   ? g : h
	 a  ?  b  :  c ?  d , e  :  f   = g

Try to determine the correct parsings before reading any farther. The
correct parsings according to the C grammar cannot both be reproduced by
applying a single consistent precedence order to all of the relevant
operators. They are:

	(a || b)      ? (d , e) : (f   ? g : h)
	(a  ? b  : (c ? (d , e) :  f)) = g

The second one is a constraint violation - the C standard requires both
that it be parsed that way, and that having been so parsed, it must be
diagnosed as a constraint violation.

Those particular expressions were chosen for a message I sent out
several months ago explaining the differences between C and C++ in the
parsing of such expressions. If you're interested, try the C++ examples:

	 a ||  b       ?  d , e  :  f   = g
	 a  ?  b  :  c ?  d , e  :  f   , g

The peculiar spacing was chosen to allow enough room to insert the
parentheses needed to indicate the correct parse, and to line up the
corresponding variables when viewed in a monospaced font.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20450

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-05-07 13:18 +0100
Message-ID<0.d8eb7be8207401a40630.20120507131802BST.87ipg8famd.fsf@bsb.me.uk>
In reply to#20449
James Kuyper <jameskuyper@verizon.net> writes:

> On 05/07/2012 05:48 AM, pete wrote:
>> somenath wrote:
> ...
>>> I tried to explain myself the outcome of 2+3*5  the way Chris Torek
>>> has explained the expression   -- - x  but I am not able to construes
>>> how the precedence of * will be enforced by the C grammar with out
>>> using operator precedence.
>> 
>> I can't do it either.
>> I use the precedence table in chapter 2 of K&R instead.
>
> What does that table say about the relative precedence of ||, ?:, =, and
> the comma operator? Using that table and the corresponding information
> about the associativity of the operators, how do you parse the two
> following expressions:
>
> 	 a ||  b       ?  d , e  :  f   ? g : h
> 	 a  ?  b  :  c ?  d , e  :  f   = g
>
> Try to determine the correct parsings before reading any farther. The
> correct parsings according to the C grammar cannot both be reproduced by
> applying a single consistent precedence order to all of the relevant
> operators. They are:
>
> 	(a || b)      ? (d , e) : (f   ? g : h)
> 	(a  ? b  : (c ? (d , e) :  f)) = g

How do you get this second parse?  It's a complex expression but it's
only the top level of it that's bugging me.

> The second one is a constraint violation - the C standard requires both
> that it be parsed that way, and that having been so parsed, it must be
> diagnosed as a constraint violation.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#20453

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-07 09:08 -0400
Message-ID<jo8hg5$71e$1@dont-email.me>
In reply to#20450
On 05/07/2012 08:18 AM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
...
>> about the associativity of the operators, how do you parse the two
>> following expressions:
>>
>> 	 a ||  b       ?  d , e  :  f   ? g : h
>> 	 a  ?  b  :  c ?  d , e  :  f   = g
>>
>> Try to determine the correct parsings before reading any farther. The
>> correct parsings according to the C grammar cannot both be reproduced by
>> applying a single consistent precedence order to all of the relevant
>> operators. They are:
>>
>> 	(a || b)      ? (d , e) : (f   ? g : h)
>> 	(a  ? b  : (c ? (d , e) :  f)) = g
> 
> How do you get this second parse?  It's a complex expression but it's
> only the top level of it that's bugging me.

I should have reviewed the entire discussion before posting that part of
it. I'd forgotten that you'd already corrected me on that issue the last
time I discussed it. The left operand of an assignment operator must be
a unary expression, so that's a syntax error, not a constraint
violation. That's not fatal to what I was trying to say, but it does
mean that this isn't the correct way to say it.
I need to modify the expression to make the point I was trying to make.
I don't have time to think about it right now, but I'll see what I can
put together later.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20455

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-05-07 14:36 +0100
Message-ID<0.c0cec614e11305a0b074.20120507143614BST.877gwof701.fsf@bsb.me.uk>
In reply to#20453
James Kuyper <jameskuyper@verizon.net> writes:

> On 05/07/2012 08:18 AM, Ben Bacarisse wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
> ...
>>> about the associativity of the operators, how do you parse the two
>>> following expressions:
>>>
>>> 	 a ||  b       ?  d , e  :  f   ? g : h
>>> 	 a  ?  b  :  c ?  d , e  :  f   = g
>>>
>>> Try to determine the correct parsings before reading any farther. The
>>> correct parsings according to the C grammar cannot both be reproduced by
>>> applying a single consistent precedence order to all of the relevant
>>> operators. They are:
>>>
>>> 	(a || b)      ? (d , e) : (f   ? g : h)
>>> 	(a  ? b  : (c ? (d , e) :  f)) = g
>> 
>> How do you get this second parse?  It's a complex expression but it's
>> only the top level of it that's bugging me.
>
> I should have reviewed the entire discussion before posting that part of
> it. I'd forgotten that you'd already corrected me on that issue the last
> time I discussed it.

I don't recall that.  In fact I seem to recall making a similar mistake
about what the syntax says because I took what gcc reports (that the LHS
of and assignment must be an lvalue) too literally.  Anyway, this has
certainly come up before.

> The left operand of an assignment operator must be
> a unary expression, so that's a syntax error, not a constraint
> violation. That's not fatal to what I was trying to say, but it does
> mean that this isn't the correct way to say it.
> I need to modify the expression to make the point I was trying to make.
> I don't have time to think about it right now, but I'll see what I can
> put together later.

I think the fact that assignment does not follow the same pattern as the
other operators is all you need to make the point that a single
precedence for each operator can't capture the formal syntax of C.

The conditional operator is tricky, but you can fix the problem by
treating the "?<expression>:" part as the operator.  Then it does behave
like a right-associative operator with a precedence between that of ||
and the assignment operators.

gcc's error reports suggest that it treats C expressions as an operator
precedence grammar and that this cases no problems because everything
that is formally a syntax error gets picked up later.  As far as the
standard is concerned, a diagnostic is a diagnostic.

Putting these two together -- treating "?<exp>:" as an operator and
giving assignment the expected priority -- means that, as programmers,
we won't go wrong just as gcc does not go wrong.  Problems will only
occur in newsgroups where the reason *why* an expression is incorrect
might matter.

I've not checked all the detail, but I don't recall every being misled
in practice by thinking of C expressions as having an operator
precedence grammar.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#20461

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-07 13:29 -0400
Message-ID<4FA8066F.9010501@verizon.net>
In reply to#20455
On 05/07/2012 09:36 AM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 05/07/2012 08:18 AM, Ben Bacarisse wrote:
>>> James Kuyper <jameskuyper@verizon.net> writes:
>> ...
>>>> about the associativity of the operators, how do you parse the two
>>>> following expressions:
>>>>
>>>> 	 a ||  b       ?  d , e  :  f   ? g : h
>>>> 	 a  ?  b  :  c ?  d , e  :  f   = g
>>>>
>>>> Try to determine the correct parsings before reading any farther. The
>>>> correct parsings according to the C grammar cannot both be reproduced by
>>>> applying a single consistent precedence order to all of the relevant
>>>> operators. They are:
>>>>
>>>> 	(a || b)      ? (d , e) : (f   ? g : h)
>>>> 	(a  ? b  : (c ? (d , e) :  f)) = g
>>>
>>> How do you get this second parse?  It's a complex expression but it's
>>> only the top level of it that's bugging me.
>>
>> I should have reviewed the entire discussion before posting that part of
>> it. I'd forgotten that you'd already corrected me on that issue the last
>> time I discussed it.
> 
> I don't recall that.  In fact I seem to recall making a similar mistake
> about what the syntax says

You did, initially. But you got it right in your message with the
following headers:

	Subject: In how many ways should this fail?
	Date: Wed, 01 Feb 2012 16:40:09 +0000

...
>> I need to modify the expression to make the point I was trying to make.
>> I don't have time to think about it right now, but I'll see what I can
>> put together later.

I was trying to demonstrate the precise limits of the use of precedence
and associativity to describe the C grammar. I provided one example
where every operand of the ?: operator had the lowest precedence allowed
by the grammar, and one example where what would otherwise qualify as
the left and right operands of the ?: operator were expressions with the
highest precedence that could not so qualify. However, I forgot to make
sure that the second expression had a valid parse. Here's the corrected
version of the second expression:

	 a  ?  b  :  c ?  d , e  :  f   , g

and the parse required by the C standard:

	(a  ?  b  : (c ? (d , e) :  f)) , g

I was really trying to make several points:

1. The grammar of C expressions that contain no syntax errors or
conditional operators can be correctly described using precedence and
associativity.
2. Many possible expressions are syntax errors for reasons that cannot
be explained using precedence and associativity; they can only be
explained by reference to the grammar.
3. Some expressions (mainly involving the middle operand of the ?:
operator) are allowed by the C grammar which cannot be explained purely
in terms of precedence and associativity.

Insofar as item 1 is true, precedence and associativity are redundant
with the grammar; because of item 2, the grammar is NOT redundant with
precedence and associativity. Those two facts alone are sufficient to
justify relying upon the grammar, rather than precedence and
associativity. The standard should NOT use both methods of description;
every key point in the standard should be expressed exactly once in the
normative text. If a requirement is expressed in two different places,
the two different expressions might conflict with each other.

Item 3 makes it clear that precedence and associativity are not merely
redundant with the grammar, but are (in rare circumstances) in conflict
with it.

I'm not opposed to thinking in terms of precedence and associativity;
they're useful concepts for most C operators. It's just important to
learn the limits of applicability of those concepts.

[toc] | [prev] | [next] | [standalone]


#20456

Frompete <pfiland@mindspring.com>
Date2012-05-07 11:24 -0400
Message-ID<4FA7E91A.5C12@mindspring.com>
In reply to#20449
James Kuyper wrote:
> 
> On 05/07/2012 05:48 AM, pete wrote:
> > somenath wrote:
> ...
> >> I tried to explain myself the outcome of 2+3*5  the way Chris Torek
> >> has explained the expression   -- - x  but I am not able to construes
> >> how the precedence of * will be enforced by the C grammar with out
> >> using operator precedence.
> >
> > I can't do it either.
> > I use the precedence table in chapter 2 of K&R instead.
> 
> What does that table say about the relative precedence of ||, ?:, =, and
> the comma operator? Using that table and the corresponding information
> about the associativity of the operators, how do you parse the two
> following expressions:
> 
>          a ||  b       ?  d , e  :  f   ? g : h
>          a  ?  b  :  c ?  d , e  :  f   = g
> 
> Try to determine the correct parsings before reading any farther. The
> correct parsings according to the C grammar cannot both be reproduced by
> applying a single consistent precedence order to all of the relevant
> operators. They are:
> 
>         (a || b)      ? (d , e) : (f   ? g : h)
>         (a  ? b  : (c ? (d , e) :  f)) = g
> 
> The second one is a constraint violation - the C standard requires both
> that it be parsed that way, and that having been so parsed, it must be
> diagnosed as a constraint violation.
> 
> Those particular expressions were chosen for a message I sent out
> several months ago explaining the differences between C and C++ in the
> parsing of such expressions. If you're interested, try the C++ examples:
> 
>          a ||  b       ?  d , e  :  f   = g
>          a  ?  b  :  c ?  d , e  :  f   , g
> 
> The peculiar spacing was chosen to allow enough room to insert the
> parentheses needed to indicate the correct parse, and to line up the
> corresponding variables when viewed in a monospaced font.

  a ||  b       ?  d , e  :  f   = g

  a ||  b       ? (d , e) :  f   = g
because ? and : form a pair of book ends, like ( and ) do.

 (a ||  b)      ? (d , e) :  f   = g
because || is stronger than ?:

((a ||  b       ? (d , e) :  f)  = g
because ?: is stronger than =


/***********************************************/

   a  ?  b  :  c ?  d , e  :  f   , g

   a  ?  b  :  c ? (d , e) :  f   , g
because ? and : form a pair of book ends, like ( and ) do.

   (a  ?  b  :  c ? (d , e) :  f)   , g
because ?: is stronger than ,

   (a  ?  b  : (c ? (d , e) :  f))  , g
because ?: associates right to left

-- 
pete

[toc] | [prev] | [next] | [standalone]


#20458

From"BartC" <bc@freeuk.com>
Date2012-05-07 16:35 +0100
Message-ID<jo8q4b$sk0$1@dont-email.me>
In reply to#20434
"somenath" <somenathpal@gmail.com> wrote in message 
news:76630b90-04ab-4976-b1a0-76868d85ccf5@vy9g2000pbc.googlegroups.com...

> Then my question is how C compiler with out bothering about precedence
> produce the same result as 2+(3*5).
>
> I tried to explain myself the outcome of 2+3*5  the way Chris Torek
> has explained the expression   -- - x  but I am not able to construes
> how the precedence of * will be enforced by the C grammar with out
> using operator precedence.

It defines the syntax so that the "+" and "*" have to be processed in a 
particular order. Then that has the same effect as using operator 
priorities, parsing to: (+ (2 (* 3 5) instead of (* (+2 3) 5)

Apparently the C syntax is complicated that way (using well over a dozen 
different levels of expressions) because of a few cases that need special 
treatment. But that didn't really work because these cases are still 
confusing even for the experts. And there are too many precedence levels 
anyway...

-- 
Bartc  

[toc] | [prev] | [next] | [standalone]


#20574

Fromjgk@panix.com (Joe keane)
Date2012-05-10 19:05 +0000
Message-ID<joh3id$fkg$1@reader1.panix.com>
In reply to#20458
In article <jo8q4b$sk0$1@dont-email.me>, BartC <bc@freeuk.com> wrote:
>And there are too many precedence levels anyway...

Precedence in C is pretty logical.

    **
    * /
    + - (unary)
    + - (binary)
    //
    FROM TO
    .EQ. .GE. .GT. .LE. .LT. .NE.
    .NOT.
    .AND.
    .OR.
    .EQV. .NEQV.
    ,
    ( )

This in turn is taken from math.

[toc] | [prev] | [next] | [standalone]


#20575

From"BartC" <bc@freeuk.com>
Date2012-05-10 20:35 +0100
Message-ID<joh5cv$bdv$1@dont-email.me>
In reply to#20574

"Joe keane" <jgk@panix.com> wrote in message 
news:joh3id$fkg$1@reader1.panix.com...
> In article <jo8q4b$sk0$1@dont-email.me>, BartC <bc@freeuk.com> wrote:
>>And there are too many precedence levels anyway...
>
> Precedence in C is pretty logical.
>
>    **
>    * /
>    + - (unary)
>    + - (binary)
>    //
>    FROM TO
>    .EQ. .GE. .GT. .LE. .LT. .NE.
>    .NOT.
>    .AND.
>    .OR.
>    .EQV. .NEQV.
>    ,
>    ( )
>
> This in turn is taken from math.

Well they don't look like C. And I'm not sure why unary ops are included in 
that lot. And whether they are logical or not, too many precedences are 
difficult to remember. I tend to use a pattern like this:

6 LOGICAL OR
5 LOGICAL AND
4 COMPARE/LOGICAL XOR [not sure what this one is doing here]
3 ADD/SUB/BITWISE AND/OR/XOR
2 MUL/DIV/MOD/SHIFT
1 POWER (right-to-left)

Since C doesn't have a power op, that leaves just 5 levels; only two of 
which are needed for normal arithmetic. A bit easier or not?

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#20587

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-11 09:25 -0400
Message-ID<joj40b$e1t$1@dont-email.me>
In reply to#20575
On 05/10/2012 03:35 PM, BartC wrote:
> 
> 
> "Joe keane" <jgk@panix.com> wrote in message 
> news:joh3id$fkg$1@reader1.panix.com...
>> In article <jo8q4b$sk0$1@dont-email.me>, BartC <bc@freeuk.com> wrote:
>>> And there are too many precedence levels anyway...
>>
>> Precedence in C is pretty logical.
>>
>>    **
>>    * /
>>    + - (unary)
>>    + - (binary)
>>    //
>>    FROM TO
>>    .EQ. .GE. .GT. .LE. .LT. .NE.
>>    .NOT.
>>    .AND.
>>    .OR.
>>    .EQV. .NEQV.
>>    ,
>>    ( )
>>
>> This in turn is taken from math.
> 
> Well they don't look like C. ...

It looks like Fortran to me; I'm not quite sure what he meant by that.

> ... And I'm not sure why unary ops are included in 
> that lot. ...

I'm not sure why you consider that odd.
The precedence of unary operators matters; otherwise *a++ could be
either (*a)++ or *(a++), and *a-b could be either *(a-b) or (*a)-b. C
gives postfix operators the highest precedence, and unary prefix
operators second highest, a distinction that neither his list nor your
list addresses. As a result, *a->b is *(a->b), not (*a)->b.

... And whether they are logical or not, too many precedences are
> difficult to remember. I tend to use a pattern like this:
> 
> 6 LOGICAL OR
> 5 LOGICAL AND
> 4 COMPARE/LOGICAL XOR [not sure what this one is doing here]
> 3 ADD/SUB/BITWISE AND/OR/XOR
> 2 MUL/DIV/MOD/SHIFT
> 1 POWER (right-to-left)

Where would =, op=, and the comma operator fit into the above scheme?

> Since C doesn't have a power op, that leaves just 5 levels; only two of 
> which are needed for normal arithmetic. A bit easier or not?

C has 16 levels, but that's partly because it covers 21 operators not
present in your list. However, the items covered by your list span 10 of
C's precedence levels, so your point still holds.

There's always a trade-off. For instance, your approach makes no
distinction between (a&b) | (c&d) and (a|b) & (c|d); they both need
parentheses in order to work as intended. C's approach is based upon the
reasonable assumption that expressions of the first form are
substantially more common than the second, so it gives binary & higher
precedence than |, rendering the parentheses unnecessary in the first form.

Of course, for people who have trouble remembering C's order of
precedence, the parenthesis are, effectively, mandatory either way, so
it's not much of a difference.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20591

From"BartC" <bc@freeuk.com>
Date2012-05-11 16:42 +0100
Message-ID<jojc23$m4$1@dont-email.me>
In reply to#20587
"James Kuyper" <jameskuyper@verizon.net> wrote in message
news:joj40b$e1t$1@dont-email.me...
> On 05/10/2012 03:35 PM, BartC wrote:
>>
>>
>> "Joe keane" <jgk@panix.com> wrote in message

>>>    //
>>>    FROM TO
>>>    .EQV. .NEQV.

>> Well they don't look like C. ...
>
> It looks like Fortran to me; I'm not quite sure what he meant by that.

But what are those funny ones like // and FROM? If // is integer division,
then why does it need to be different from /?

>> ... And I'm not sure why unary ops are included in
>> that lot. ...
>
> I'm not sure why you consider that odd.
> The precedence of unary operators matters; otherwise *a++ could be
> either (*a)++ or *(a++), and *a-b could be either *(a-b) or (*a)-b. C
> gives postfix operators the highest precedence, and unary prefix
> operators second highest, a distinction that neither his list nor your
> list addresses. As a result, *a->b is *(a->b), not (*a)->b.

Unary ops are executed before binary ones, so they shouldn't even be in the
same list. I'd've thought that was pretty standard (in the same way that you
don't need to add parentheses to such a list.

And they would naturally be executed from the inside outwards, so precedence
doesn't matter there.

It's only an issue where unary ops can appear on either side of a term, as
in your examples. The precedence table in K&R2 suggests that a series of
unary ops such as op1 op2 A op3 op4 should be calculated as op1(op2((A op4)
op3)) (with 3 and 4 interchanged). They are confusing.

> ... And whether they are logical or not, too many precedences are
>> difficult to remember. I tend to use a pattern like this:
>>
>> 6 LOGICAL OR
>> 5 LOGICAL AND
>> 4 COMPARE/LOGICAL XOR [not sure what this one is doing here]
>> 3 ADD/SUB/BITWISE AND/OR/XOR
>> 2 MUL/DIV/MOD/SHIFT
>> 1 POWER (right-to-left)
>
> Where would =, op=, and the comma operator fit into the above scheme?

If you write the following:

 A = B op C;

you would naturally expect B op C, what op happens to be, to be done before 
the assignment. This suggests assignment should always be done last, and 
belongs (with assign-op combinations) at the top of my list).

>> Since C doesn't have a power op, that leaves just 5 levels; only two of
>> which are needed for normal arithmetic. A bit easier or not?
>
> C has 16 levels, but that's partly because it covers 21 operators not
> present in your list. However, the items covered by your list span 10 of
> C's precedence levels, so your point still holds.

16 is too many (so is 15, the number listed by K&R). Why is == different 
from <= for example? While <<,>> belong with multiply and divide. And if I 
read the table properly, then a & b == c & d actually means a & (b==c) & d; 
that obviously doesn't look right, not for bitwise & anyway.

> There's always a trade-off. For instance, your approach makes no
> distinction between (a&b) | (c&d) and (a|b) & (c|d); they both need
> parentheses in order to work as intended.

Those bitwise and/or levels may be a mistake; & should be the same as
multiply, and | the same as add (because & and * can be both be used for set
intersection, and | and + can both be used for set union; and yes I know C
doesn't have sets...).

This all means only 2-3 levels to remember for normal arithmetic, and
another 3 (compare, and, or) for conditional expressions.

Stuff such as assignments, () and 'comma' I would consider language
constructs not operators. The ?: op I would also implement as a construct,
but with mandatory parentheses.

-- 
Bartc
 

[toc] | [prev] | [next] | [standalone]


#20596

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-11 12:28 -0400
Message-ID<4FAD3E13.7000804@verizon.net>
In reply to#20591
On 05/11/2012 11:42 AM, BartC wrote:
> "James Kuyper" <jameskuyper@verizon.net> wrote in message
> news:joj40b$e1t$1@dont-email.me...
>> On 05/10/2012 03:35 PM, BartC wrote:
>>>
>>>
>>> "Joe keane" <jgk@panix.com> wrote in message
> 
>>>>    //
>>>>    FROM TO
>>>>    .EQV. .NEQV.
> 
>>> Well they don't look like C. ...
>>
>> It looks like Fortran to me; I'm not quite sure what he meant by that.
> 
> But what are those funny ones like // and FROM? If // is integer division,
> then why does it need to be different from /?

I've no idea - the last time I did any significant Fortran programming
was 2 decades ago, in VMS Fortran. There have been two or three?
revisions to the Fortran standard since then, including a lot of new
features that make it a very different language. I can't vouch for
whether // and FROM might be two of those new features, but the rest of
list looked like Fortran to me.

> 
>>> ... And I'm not sure why unary ops are included in
>>> that lot. ...
>>
>> I'm not sure why you consider that odd.
>> The precedence of unary operators matters; otherwise *a++ could be
>> either (*a)++ or *(a++), and *a-b could be either *(a-b) or (*a)-b. C
>> gives postfix operators the highest precedence, and unary prefix
>> operators second highest, a distinction that neither his list nor your
>> list addresses. As a result, *a->b is *(a->b), not (*a)->b.
> 
> Unary ops are executed before binary ones, so they shouldn't even be in the
> same list.

This is about hierarchy within the parse tree, not execution order. The
parse tree imposes some constraints on the execution order, but does not
determine it. In the expression *a + ~b * !c, *a need not be evaluated
until after the multiplication.

The features of the grammar that give postfix and prefix operators
higher precedence than the other operators are precisely why they they
go before the other ones.

> ... I'd've thought that was pretty standard (in the same way that you
> don't need to add parentheses to such a list.
> 
> And they would naturally be executed from the inside outwards, so precedence
> doesn't matter there.
> It's only an issue where unary ops can appear on either side of a term, as

Which is precisely why unary ops in C occupy two different precedence
levels, one for postfix and one for prefix operators.

> in your examples. The precedence table in K&R2 suggests that a series of
> unary ops such as op1 op2 A op3 op4 should be calculated as op1(op2((A op4)
> op3)) (with 3 and 4 interchanged). They are confusing.

That's a rather confusing statement. Why did you write "with 3 and 4
interchanged" rather than simply interchanging 3 and 4?

>> ... And whether they are logical or not, too many precedences are
>>> difficult to remember. I tend to use a pattern like this:
>>>
>>> 6 LOGICAL OR
>>> 5 LOGICAL AND
>>> 4 COMPARE/LOGICAL XOR [not sure what this one is doing here]
>>> 3 ADD/SUB/BITWISE AND/OR/XOR
>>> 2 MUL/DIV/MOD/SHIFT
>>> 1 POWER (right-to-left)
>>
>> Where would =, op=, and the comma operator fit into the above scheme?
> 
> If you write the following:
> 
>  A = B op C;
> 
> you would naturally expect B op C, what op happens to be, to be done before 
> the assignment. This suggests assignment should always be done last, and 
> belongs (with assign-op combinations) at the top of my list).

So you need an additional level for that, too. In C, it's not the lowest
precedence, so a , b = c is parsed as a, (b = c), not (a,b)=c (which
would be a constraint violation).

Because C uses grammar productions rather than precedence tables, the
expression a ? b = c : d is not the syntax error (a?b) = (c:d), but is
instead a ? (b=c) : d.

>>> Since C doesn't have a power op, that leaves just 5 levels; only two of
>>> which are needed for normal arithmetic. A bit easier or not?
>>
>> C has 16 levels, but that's partly because it covers 21 operators not
>> present in your list. However, the items covered by your list span 10 of
>> C's precedence levels, so your point still holds.
> 
> 16 is too many (so is 15, the number listed by K&R). Why is == different 
> from <= for example? While <<,>> belong with multiply and divide. And if I 
> read the table properly, then a & b == c & d actually means a & (b==c) & d; 
> that obviously doesn't look right, not for bitwise & anyway.

Not all of the choices made for operator precedence were good ones;
IIRC, Ritchie himself acknowledged that fact. In a new language where
backwards compatibility was not an issue, they should be done
differently. But I don't think that fewer precedence levels is the way
to go.

[toc] | [prev] | [next] | [standalone]


#20608

From"BartC" <bc@freeuk.com>
Date2012-05-11 18:42 +0100
Message-ID<jojkr0$r88$1@dont-email.me>
In reply to#20596
"James Kuyper" <jameskuyper@verizon.net> wrote in message 
news:4FAD3E13.7000804@verizon.net...
> On 05/11/2012 11:42 AM, BartC wrote:

>> Unary ops are executed before binary ones, so they shouldn't even be in 
>> the
>> same list.
>
> This is about hierarchy within the parse tree, not execution order. The
> parse tree imposes some constraints on the execution order, but does not
> determine it. In the expression *a + ~b * !c, *a need not be evaluated
> until after the multiplication.

For unary operators, I think hierarchy matches execution order.

> The features of the grammar that give postfix and prefix operators
> higher precedence than the other operators are precisely why they they
> go before the other ones.
>
>> ... I'd've thought that was pretty standard (in the same way that you
>> don't need to add parentheses to such a list.
>>
>> And they would naturally be executed from the inside outwards, so 
>> precedence
>> doesn't matter there.
>> It's only an issue where unary ops can appear on either side of a term, 
>> as
>
> Which is precisely why unary ops in C occupy two different precedence
> levels, one for postfix and one for prefix operators.

Do they? In the K&R table, they seem to occupy one level.

>> in your examples. The precedence table in K&R2 suggests that a series of
>> unary ops such as op1 op2 A op3 op4 should be calculated as op1(op2((A 
>> op4)
>> op3)) (with 3 and 4 interchanged). They are confusing.
>
> That's a rather confusing statement. Why did you write "with 3 and 4
> interchanged" rather than simply interchanging 3 and 4?

Because you might have thought it a typo otherwise. K&R says unary ops 
associate from  right to left. So op4 first.

>> If you write the following:
>>
>>  A = B op C;
>>
>> you would naturally expect B op C, what op happens to be, to be done 
>> before
>> the assignment. This suggests assignment should always be done last, and
>> belongs (with assign-op combinations) at the top of my list).
>
> So you need an additional level for that, too. In C, it's not the lowest
> precedence, so a , b = c is parsed as a, (b = c), not (a,b)=c (which
> would be a constraint violation).

Yes, you can think of it as an extra level, but it can just be the grammar. 
The main thing you don't need to stop and think about it.

> Because C uses grammar productions rather than precedence tables, the
> expression a ? b = c : d is not the syntax error (a?b) = (c:d), but is
> instead a ? (b=c) : d.

The three-way ?: is too weird to even have as operator. How would you even 
parenthesise it so that ?: is done before the assignment? Besides, according 
to the precedence table, ?: comes before assignment!

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#20612

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-11 15:18 -0400
Message-ID<4FAD65F5.5040605@verizon.net>
In reply to#20608
On 05/11/2012 01:42 PM, BartC wrote:
> "James Kuyper" <jameskuyper@verizon.net> wrote in message 
> news:4FAD3E13.7000804@verizon.net...
...
>> This is about hierarchy within the parse tree, not execution order. The
>> parse tree imposes some constraints on the execution order, but does not
>> determine it. In the expression *a + ~b * !c, *a need not be evaluated
>> until after the multiplication.
> 
> For unary operators, I think hierarchy matches execution order.

Yes, if you only consider the unary operators, it's simple. However, the
minute you throw in binary operators, the issue does comes up. C deals
with that issue by specifying a grammar that gives the postfix operators
(both unary and binary) the highest precedence and left-to-right
associativity, and gives the unary prefix operators the next-highest
precedence, with right-to-left associativity. All other operators (most
of them binary) have a lower precedence.

...
>> Which is precisely why unary ops in C occupy two different precedence
>> levels, one for postfix and one for prefix operators.
> 
> Do they? In the K&R table, they seem to occupy one level.

The relevant grammar rules are 6.5.2p1:
   postfix-expression:
            primary-expression
            postfix-expression [ expression ]
            postfix-expression ( argument-expression-listopt )
            postfix-expression . identifier
            postfix-expression -> identifier
            postfix-expression ++
            postfix-expression --
            ( type-name ) { initializer-list }
            ( type-name ) { initializer-list , }

and 6.5.3p1:
    unary-expression:
           postfix-expression
           ++ unary-expression
           -- unary-expression
           unary-operator cast-expression
           sizeof unary-expression
           sizeof ( type-name )
           _Alignof ( type-name )

The aspect of the grammar which can be described by precedence tables is
encoded in the grammar by the fact that a postfix-expression can be
parsed as a unary-expression, but a unary-expression cannot be parsed as
a postfix-expression.

>>> in your examples. The precedence table in K&R2 suggests that a series of
>>> unary ops such as op1 op2 A op3 op4 should be calculated as op1(op2((A 
>>> op4)
>>> op3)) (with 3 and 4 interchanged). They are confusing.
>>
>> That's a rather confusing statement. Why did you write "with 3 and 4
>> interchanged" rather than simply interchanging 3 and 4?
> 
> Because you might have thought it a typo otherwise. K&R says unary ops 
> associate from  right to left. So op4 first.

Sorry - I misunderstood. I thought you were choosing a bizarre way of
expressing the correct parse, which is (A op3) op4.

There are only two unary postfix operators, the other postfix operators
are all binary. According to the grammar, a++-- can only be  parsed as
(a++)--, not as (a--)++. It hardly matters, though: postfix ++ and --
both require modifiable lvalues for their left operand (6.5.3.1p2), and
neither one has a result which is an lvalue. Therefore, after correctly
parsing any consecutive pair of unary postfix operators, an
implementation must diagnose a constraint violation. As a result,
associativity is pretty much irrelevant for unary postfix operators.

The associativity of postfix operators only comes up in combination with
the binary postfix operators. It's encoded in the grammar by the fact
that every grammar production for a postfix-expression that also
contains a postfix-expression contains it only on the left side of the
production, not on the right. In other words, they associate from left
to right. For instance, a.b++ is parsed as (a.b)++, not as a.(b++),
because the right operand of the member-selection operator must be an
identifier, while the left operand of postfix ++ can be another
postfix-expression.
If the grammar had mandated the second parse, rather than the first, the
result would have been a constraint violation, but it would first have
had to be correctly parsed before it could be recognized as one.

In contrast, every grammar production for unary-expression that contains
a unary-expression, contains it on the right end of the production.
That's why the prefix unary operators can be correctly described as
associating from right to left.

...
>> So you need an additional level for that, too. In C, it's not the lowest
>> precedence, so a , b = c is parsed as a, (b = c), not (a,b)=c (which
>> would be a constraint violation).
> 
> Yes, you can think of it as an extra level, but it can just be the grammar. 

Well yes, in C, it's all grammar; precedence and associativity are
merely descriptions of important features of that grammar. The process
of deriving a precedence and associativity table for C naturally starts
with the postfix operators and ends with the comma operator. Starting it
with || and ending it with the multiplicative operators is rather
arbitrary. You could just as easily have chosen to start it at the
additive operators.

>> Because C uses grammar productions rather than precedence tables, the
>> expression a ? b = c : d is not the syntax error (a?b) = (c:d), but is
>> instead a ? (b=c) : d.
> 
> The three-way ?: is too weird to even have as operator. How would you even 
> parenthesise it so that ?: is done before the assignment? Besides, according 
> to the precedence table, ?: comes before assignment!

Yes, that's the one way in which precedence tables necessarily fail to
correctly describe the C grammar. Take out the ?: operator, and a
correctly written precedence table could be a perfectly accurate
description of one aspect of the grammar.

[toc] | [prev] | [next] | [standalone]


#20631

From"BartC" <bc@freeuk.com>
Date2012-05-11 22:52 +0100
Message-ID<jok1ne$b7p$1@dont-email.me>
In reply to#20612
"James Kuyper" <jameskuyper@verizon.net> wrote in message
news:4FAD65F5.5040605@verizon.net...
> On 05/11/2012 01:42 PM, BartC wrote:
>> "James Kuyper" <jameskuyper@verizon.net> wrote in message
>> news:4FAD3E13.7000804@verizon.net...
> ...
>>> This is about hierarchy within the parse tree, not execution order. The
>>> parse tree imposes some constraints on the execution order, but does not
>>> determine it. In the expression *a + ~b * !c, *a need not be evaluated
>>> until after the multiplication.
>>
>> For unary operators, I think hierarchy matches execution order.
>
> Yes, if you only consider the unary operators, it's simple. However, the
> minute you throw in binary operators, the issue does comes up. C deals
> with that issue by specifying a grammar that gives the postfix operators
> (both unary and binary)

I'm not too well up on the right terminology, but wouldn't any binary
operator just be 'infix'?

>>> Which is precisely why unary ops in C occupy two different precedence
>>> levels, one for postfix and one for prefix operators.
>>
>> Do they? In the K&R table, they seem to occupy one level.
>
> The relevant grammar rules are 6.5.2p1:
...

Actually, I've made use of C-style postfix ++,-- operators in my own
projects. They are parsed as they are in C. (But I don't any special concept 
of precedence, and a much simpler grammar.)

> There are only two unary postfix operators, the other postfix operators
> are all binary. According to the grammar, a++-- can only be  parsed as
> (a++)--, not as (a--)++. It hardly matters, though: postfix ++ and --
> both require modifiable lvalues for their left operand (6.5.3.1p2), and
> neither one has a result which is an lvalue.

(Yes, well, I worry about lvalues in a later pass. My parser only deals
with 'shape'.)

> Therefore, after correctly
> parsing any consecutive pair of unary postfix operators, an
> implementation must diagnose a constraint violation. As a result,
> associativity is pretty much irrelevant for unary postfix operators.

> to right. For instance, a.b++ is parsed as (a.b)++, not as a.(b++),

(That's a good point; just needed a quicker check my parser does the same,
which fortunately it did. But then, I don't treat "." (or "->") as an
operator at all; it can't be an operator because the right operand can't be 
a conventional expression.)

>> The three-way ?: is too weird to even have as operator. How would you
>> even
>> parenthesise it so that ?: is done before the assignment? Besides,
>> according
>> to the precedence table, ?: comes before assignment!
>
> Yes, that's the one way in which precedence tables necessarily fail to
> correctly describe the C grammar. Take out the ?: operator, and a
> correctly written precedence table could be a perfectly accurate
> description of one aspect of the grammar.

So the issue is really K&R over-simplifying matters in their operator table,
by including constructs which are not conventional operators in syntax or
semantics (such as "()" and "[]").

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web