Re: Re: help please?

Kenny MacDermid <[email protected]> Sun, 2 May 2004 01:07:47 -0300
Newsgroups gmane.comp.lang.prothon.devel
Message-ID <[email protected]>
On Sat, May 01, 2004 at 03:22:34PM -0700, Mark Hahn wrote:
> Kenny MacDermid wrote:
> > I really have no idea right at the moment.

Some beers and pool seem to have helped. I believe I've figured
it out.

It's the same reason you found you needed %prec rules like:

|   DEF_ '.' LABEL %prec UDOT

Your last precedence declaration is:

%nonassoc <str_type>    LABEL

Saying that labels are the highest precedence thing you can
have. Also Bison assigns precedence for rules based on the
*last* terminal symbol in the rule. This means if you had:

exp: exp '*' NUMBER;

then this would match with a precedence of NUMBER, and not
'*', as you might expect (and usually want). To fix this you
just have to switch the last terminal to a non-terminal like:

exp: exp '*' num;
num: NUMBER;

Now the exp will match with a precedence of '*', and will act
as expected.

--------

Now looking at the prothon grammer we have:

%nonassoc '('
%nonassoc LABEL

%%

obj:
    obj '$' LABEL
    obj '$' LABEL '(' function_params ')'
    ;

Now when we get to the state:

obj -> obj '$' LABEL .
next: '('

and we're trying to decide what to do, we look at this:

we could reduce using rule "obj '$' LABEL" which has a high precedence
or we could shift on '(' which has a lower precedence

therefor we decide that we should reduce using the first rule
and then handle the '(' later (as it's less important).

-----------

Follow me so far? Hopefully I'm making any sense after the
beers :-) . I'm not sure how much you know on the workings of
shift/reduce parsers so if I'm talking greek please tell me.

Okay, so how I would fix this would be (and I can make a patch
tomorrow if you like, but I can't test against your test cases
yet):

1: make a non-terminal along the lines of:

label: LABEL
    ;

2: replace all rules pointing at LABEL with label

3: set:
%type <str_type> label

--- this will fix that obj rule, but just for good measure:

4: cleanup the %prec for rules that use to contain LABEL at
the end, they should no longer be needed

5: LABEL is not a thing you do to something, or between two
things, so precedence doesn't really make sense for it.
Change:

%nonassoc <str_type> LABEL

to:

%token <str_type> LABEL

This will make it have no precedence, but still define it's
type.

--- this step may need testing, nothing should be counting on
the precedence of a label, but it might flip a conflict the
other way

6: fix up other precedence list cases. Try to only give
precedence to things that need it. And only to ones that make
sense (that are in-between two things like '+'). Put all equal
precedences together like:

%left '+' '-'
%left '<' LE '>' GE NE EQ

(this should allow the remove all the %prec EQ)

----------

That should do it, and it's getting a little late here (or
early I suppose), so I'll hope when I read this tomorrow it
actually makes a little bit of sense (beer==good), and say
goodnight for now,

Kenny