> Ok, thanks, this seems to have solved it.
> So the %nonassoc says to the parser that
> (REP block) ATOM
> is the right decision as opposed to
> REP (block ATOM)
> right?

%token declares its arguments as tokens but
does not give them any precedence level.

%left, %right, and %nonassoc also declare their
arguments as tokens.  in addition, each such line
introduces a new precedence level stronger than
the ones introduced by previous lines.

if a shift/reduce conflict involves different precedences,
the stronger precedence always wins.

if a shift/reduce conflict is a tie between identical precedences,
the resolution depends on which of the three lines
(%left, %right, or %nonassoc) introduced the precedence.

precedences introduced by %left resolve the tie
by reducing; this creates left-to-right associativity (x-y-z).

precedences introduced by %right resolve the tie
by shifting; this creates right-to-left associativity (x^y^z in hoc).

precedences introduced by %nonassoc do not resolve
the tie.  they leave it as a conflict that gets reported.

if you're defining a precedence that is not intended
to be associative, much of the time it doesn't matter
which you pick, because your grammar is likely to
be such that ties never happen.  but %nonassoc is
still the safe choice.

in the running example, %nonassoc by itself
doesn't say which of those two is right.  it just
defines a precedence for ATOM, which is used
as the precedence for shifting ATOM.
because the REP block and block block rules
have precedences too, the ambiguity can be
resolved by comparing the precedences.
which way things get resolved depends on whether
the %nonassoc line comes before or after the
other precedences, not on the meaning of %nonassoc.

i said

> %left '+'
> %left REP
> %nonassoc ATOM

and that will give you REP block ATOM == REP (block ATOM)
which is probably not what you want.  to tweak it,
just move the %nonassoc line above the two %left lines.

russ

Reply via email to