Pcc bites it

Greg Limes limes at wseng.sun.com
Tue Mar 21 16:21:53 AEST 1989


In article <15936 at cup.portal.com> Tim_CDC_Roberts at cup.portal.com writes:

>  In <2550086 at hpisod2.HP.COM>, decot at hpisod2.HP.COM (Dave Decot) writes:

>  >>    (n&&m) *= n--
>  > ... doesn't have two different valid interpretations, so it's not
>  > ambiguous, so the precedence rules are not applicable.

>  I disagree with this statement.  The parser does not necessarily have
>  any knowledge about whether a construct is _semantically_ valid.  It
>  is attempting to make a _syntactically_ valid interpretation, and BOTH
>  interpretations [ (n&&m) *= n--  vs.  n && (m*=n--) ] are syntactically
>  valid.

[[disclaimer at the top: the last C compiler I wrote was about five
years ago; the grammar below is excerpted from dusty memories. I am
looking forward to getting my hands on the BNF for ANSI C.]]

Depends on how you write your syntax. If, for instance, you separate
the concept of "lvalue" (something you can assign to) from "expr" in
the parser instead of pushing that task downstream. For instance,
given this segment of a grammar:

	lval ::= IDENT
	lval ::= lval POSTOP
	expr ::= lval ASGOP expr
	expr ::= expr BINOP expr
	expr ::= lval

And this input:

	n&&m*=n--

The tokens emitted by the lexical analiser:

	IDENT BINOP IDENT ASGOP IDENT POSTOP

I contend that the reduction via the BINOP is delayed until after the
reduction via the ASGOP, simply because it is the only way that you
come to a valid parsing of the statement. The parser simply has no
choice; when it has shifted the second IDENT and reduced it to an
lval, and is considering what to do next, the following ASGOP forces
it to shift the asgop onto the stack, and defer the reduction on the
BINOP until later, since the result of such a reduction can not
possibly be on the left side of the ASGOP.

Just to be sure I am on the right track here, any compiler wizzes out
there want to take a look at a simple action trace for me?

 stack					token	action
					IDENT	shift
 IDENT					BINOP	reduce(1)
 lval					BINOP	reduce(5)
 expr					BINOP	shift
 expr BINOP				IDENT	shift
 expr BINOP IDENT			ASGOP	reduce(1)
 expr BINOP lval			ASGOP	reduce(1)
 expr BINOP lval ASGOP			IDENT	shift
 expr BINOP lval ASGOP IDENT		POSTOP	reduce(1)
 expr BINOP lval ASGOP lval		POSTOP	shift
 expr BINOP lval ASGOP lval POSTOP	<end>	reduce(2)
 expr BINOP lval ASGOP lval		<end>	reduce(3)
 expr BINOP expr			<end>	reduce(4)
 expr					<end>

I look forward to finding out what has changed in the C language that
would invalidate this parsing. 



More information about the Comp.lang.c mailing list