Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!decwrl!sun!limes From: limes@wseng.sun.com (Greg Limes) Newsgroups: comp.lang.c Subject: Re: Pcc bites it Message-ID: Date: 21 Mar 89 06:21:53 GMT References: <28336@ucbvax.BERKELEY.EDU> <2550086@hpisod2.HP.COM> <15936@cup.portal.com> Sender: news@sun.Eng.Sun.COM Distribution: na Organization: Sun Microsystems, Inc. Lines: 67 In-reply-to: Tim_CDC_Roberts@cup.portal.com's message of 17 Mar 89 17:31:57 GMT In article <15936@cup.portal.com> Tim_CDC_Roberts@cup.portal.com writes: > In <2550086@hpisod2.HP.COM>, decot@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 reduce(2) expr BINOP lval ASGOP lval reduce(3) expr BINOP expr reduce(4) expr I look forward to finding out what has changed in the C language that would invalidate this parsing.