[comp.lang.c] ambiguous why?

edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (04/05/88)

When I was playing around with that last example I posted, I got an
error message that said something to the extent:

	warning ambiguous assigment: assignment op taken
	syntax error at or near symbol *=

A simplified version of the statement is:

	int *a, *b;

	*a+=*b;

I thought that this should not be ambiguous since the lexer scans left to right.
Is there some l to r rule that disambiguates this statement or did I
just make it up?
-- 

Eddie Wyatt 				e-mail: edw@ius1.cs.cmu.edu

chris@mimsy.UUCP (Chris Torek) (04/05/88)

In article <1303@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
>... I got an error message that said something to the extent:
> 	warning ambiguous assigment: assignment op taken

C used to have =op operators; it now has op= operators.  In `old C'
one wrote, e.g.,

	i =- 1;

rather than

	i -= 1;

This meant that a statement such as

	i=-1;

was uncertain: did you mean decrement i by 1, or did you mean
assign -1 to i?  In `old C' the answer was to decrement i.

Some compilers (notably PCC) have accepted and warned about `old
fashioned' assignment operators for nearly 10 years.  The above
warning is given whenever the compiler sees `=-', to tell you
that it was not sure whether you meant `= -' or `-=', but that
it assumed the latter.  In particular, if you write

	int i=-1;

the compiler thinks you meant

	int i -= 1;

which is syntactically incorrect.

The easiest fix for this is to remove the `old C' compatibility
support.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

mesard@bbn.com (Wayne Mesard) (04/05/88)

From article <1303@PT.CS.CMU.EDU>, by edw@IUS1.CS.CMU.EDU (Eddie Wyatt):
> I got an
> error message that said something to the extent:
> 
> 	warning ambiguous assigment: assignment op taken
> 	syntax error at or near symbol *=
> 
> A simplified version of the statement is:
> 
> 	int *a, *b;
> 
> 	*a+=*b;
> 
> I thought that this should not be ambiguous since the lexer scans left to right.

K&R A.17 talks about earlier versions of C which used the form "=op"
instead of "op=".  Most(?) compilers still try to detect the old form
and issue a warning.  In my opinion this causes headaches more than it
catches obsolete code.  Anyway, the compiler wasn't sure if you wanted
"addition assignment" (+=) or the old multiplication assignment (=*) so
it complained.  Putting a space after the "=" fixes it:

	int *a, *b;

	*a+= *b;

I usually run into this in the first expression of a for statement:

	for (a=-1; ++a < N;)
	   ...

Which serves me right, since readability and good taste dictate that I
should have spaces around my assignment ops anyway.

Now here's one for you puritans and compiler whiz-kids:

K&R 7.14 says "The two parts of a compound assignment operator are
separate tokens."  Doesn't this mean that the spaces (absense or
presense of) shouldn't matter?  Indeed they are separate tokens since
the following code works:

	a  +  =  b;

-- 
unsigned *Wayne_Mesard();                     MESARD@BBN.COM
                                              BBN Labs, Cambridge, MA
After all, Sodom wasn't built in a day.

karl@haddock.ISC.COM (Karl Heuer) (04/05/88)

In article <1303@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
>	warning ambiguous assigment: assignment op taken
>	*a+=*b;

Your compiler scans "+=" as two tokens rather than one.  (Fixed in dpANS.)
This makes the anachronism "=*" (fixed in dpANS) visible.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (04/06/88)

> > 	*a+=*b;
> > 
> 
> K&R A.17 talks about earlier versions of C which used the form "=op"
> instead of "op=".  Most(?) compilers still try to detect the old form
> and issue a warning.  In my opinion this causes headaches more than it
> catches obsolete code.  Anyway, the compiler wasn't sure if you wanted
> "addition assignment" (+=) or the old multiplication assignment (=*) so
> it complained.  Putting a space after the "=" fixes it:

  This doesn't answer my question.  I am familiar with the old
syntax for operand assignment.  I understand that without some sort of
lexer rule, the above is ambiguous.  However, I thought that a
rule existed that should disambiguated this statement.  In particular,
I do believe a rule exist such that you choose the largest token
posible as you scan left to right.  That is why the statement a+++b is
not ambiguous (optional read a++ + b).

   If what you wrote about the tokenization of +=  (two separate tokens + =)
is correct then the above statement is ambiguous at the parsing level.
In which case I could understand there not existing a disambiguating rule.


-- 

Eddie Wyatt 				e-mail: edw@ius1.cs.cmu.edu

edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (04/06/88)

 >>	warning ambiguous assigment: assignment op taken
 >>	*a+=*b;
 > 
 > Your compiler scans "+=" as two tokens rather than one.  (Fixed in dpANS.)
 > This makes the anachronism "=*" (fixed in dpANS) visible.

  What a f***ing hack =* is then!!!!   If *= consists of two tokens
so should =* which obviously doesn't because if it did then
neither =* nor = * would be distinguishable by the parser.


-- 

Eddie Wyatt 				e-mail: edw@ius1.cs.cmu.edu

rsalz@bbn.com (Rich Salz) (04/06/88)

Eddie Wyatt asks why this
	*a+=*b;
gives this message:
	warning ambiguous assigment: assignment op taken
The Walking Lint replies:
	Your compiler scans "+=" as two tokens rather than one.

Yeah, that's obviously what it's doing, but it's wrong.  The Rules say to
take the longest possible token you can, so "*a+=*b" should be parsed as
	* a += * b

Sounds like Eddie's found a compiler bug.
	/r$
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.

davidsen@steinmetz.steinmetz.ge.com (William E. Davidsen Jr) (04/06/88)

In article <1303@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
| When I was playing around with that last example I posted, I got an
| error message that said something to the extent:
| 
| 	warning ambiguous assigment: assignment op taken
| 	syntax error at or near symbol *=
| 
| A simplified version of the statement is:
| 
| 	int *a, *b;
| 
| 	*a+=*b;

Older versions of C allowed =+ =* etc as assignment forms. Later
versions switched to *= and += so that the unary minus would not be
ambiguous. Your compiler is seeing the =* and complaining.

Ambiguous to the eye but not the compiler:
	d = a+++b;

The compiler should go left to right and take the longest valid sequence
of characters, so the result is:
	d = a++ + b;

Perhaps someone will find the reference in ANSI for this and post it.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

karl@haddock.ISC.COM (Karl Heuer) (04/07/88)

In article <1325@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
>>>	warning ambiguous assigment: assignment op taken  [*a+=*b;]
>>Your compiler scans "+=" as two tokens rather than one.  (Fixed in dpANS.)
>>This makes the anachronism "=*" (fixed in dpANS) visible.
>
>What a f***ing hack =* is then!!!!   If *= consists of two tokens
>so should =* which obviously doesn't

As I said, "fixed in dpANS".  The former by insisting that "+=" is one token;
the latter by removing the anachronism.  (The stupid thing has been obsolete
for about 10 years, and there are *still* compilers out there that assume you
must have meant the compound assignment operator!)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

hankd@pur-ee.UUCP (Hank Dietz) (04/07/88)

Your compiler said it was ambiguous because it didn't know whether you
gave it old-style C or new C... not because it is ambiguous in a formal
parsing/lexical analysis sense....  In fact, *a+=*b has only one legal
interpretation because if the + is taken as an operator unto itself,
then there is no legal (error-free) interpretation of the =.

Now that X3J11 has bid final farewell to the =op stuff, it is sort-of
a moot point, but has anyone else noticed that the usual confusion
with =op can be resolved by using TYPE infromation?  For example:

a=*b;		This is a*=b; iff a and b are types which can be
		multiplied, i.e., not pointers, whereas it is
		a=(*b); if b is a pointer.
a=&b;		Similar observation about type-viability of a&b
		versus &b....
a=-b;		Generally ambiguous, but not if we are dealing
		with unsigned quantities (e.g., pointers).

Does anyone know of a compiler which attempts type-based
disambiguation of the old-fashioned assignment operators?

flaps@dgp.toronto.edu (Alan J Rosenthal) (04/08/88)

Eddie Wyatt and Rich Salz both write that i+=*p shouldn't be ambiguous
because there is a rule that says that the lexer should always take the
longest possible token.

However, I think they are confusing different kinds of ambiguity.  :-)
One is an ambiguity between interpretations of expressions given a
certain set of rules, and the other is an ambiguity between deciding
which set of rules to use.

When scanning `+=*', older compilers would ALWAYS take the token list
to be `+' and `=*'.  Newer compilers, based on the rule that the
scanner should always take the longest possible token, would ALWAYS
take the token list to be `+=' and `*'.[1]  If you're writing a
compiler which is supposed to act correctly in either circumstance,
this code is ambiguous.

ajr

--

[1] In effect.

-- 
"Comment, Spock?"
"Very bad poetry, Captain."

sjoerd@cs.vu.nl (Sjoerd Mullender) (04/08/88)

In article <1303@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
[ complains that "*a+=*b;" gives a warning about an ambiguous assignment ]

There are compilers (pcc comes to mind) that consider "op =" to be two tokens,
whereas they consider "= op" to be one token.
So your code fragment is tokenized as follows:

	*
	a
	+
	=*	gives a warning
	b
	;
-- 
Sjoerd Mullender
sjoerd@cs.vu.nl
When this doesn't work try sending via seismo.css.gov or mcvax.uucp.

dkc@hotlr.ATT (Dave Cornutt) (04/09/88)

In article <1303@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
 > When I was playing around with that last example I posted, I got an
 > error message that said something to the extent:
 > 
 > 	warning ambiguous assigment: assignment op taken
 > 	syntax error at or near symbol *=
 > 
 > A simplified version of the statement is:
 > 
 > 	int *a, *b;
 > 
 > 	*a+=*b;
 > 
 > I thought that this should not be ambiguous since the lexer scans left to right.
 > Is there some l to r rule that disambiguates this statement or did I
 > just make it up?

The tipoff is the "*=" in the error message.  You have a compiler that
still recoginzes the old turned-around operator syntax.  (Back in the
bad old days, this statement:

	a =- b

used to mean "subtract b from a and assign the result to a", where it
now means "negate b and assign that value to a".  If you put a space
in between the '=' and the '*', that should get your compiler to
shut up.

(P.S: Is dpANS finally going to get rid of this?  I hope so.)


-- 
Dave Cornutt, AT&T Bell Labs (rm 4A406,x1088), Holmdel, NJ
UUCP:{ihnp4,allegra,cbosgd}!hotly!dkc
"The opinions expressed herein are not necessarily my employer's, not
necessarily mine, and probably not necessary"