I can’t tell just now if this is the right place to be sending bug reports for 
Lemon. I have identified a failing in the handling of nonassoc precedence with 
the generated grammars.

I detailed my findings in this StackOverflow page: 
http://stackoverflow.com/questions/24051458/is-lemon-correctly-handling-nonassoc-precedence/24093576#24093576

Basically it comes down like this. I took a tiny grammar for example:
%nonassoc EQ.
%left PLUS.

stmt ::= expr.

expr ::= expr EQ expr.
expr ::= expr PLUS expr.
expr ::= IDENTIFIER.
And this generated a conflict when handling the second EQ in a series (so 
something like x=y=z). The rules for nonassoc state this should be an error, 
but the grammar does not detect it as such. Instead, a shift/reduce conflict 
gets entered into the grammar.
State 4:
      expr ::= expr * EQ expr
  (1) expr ::= expr EQ expr *
      expr ::= expr * PLUS expr

                        EQ shift  2
                        EQ reduce 1   ** Parsing conflict **
                      PLUS shift  1
                 {default} reduce 1
I have locally modified the source the get around the issue, adding a branch to 
the shift/reduce logic like so:
        if( apx->type==SHIFT && apy->type==REDUCE ){
                spx = apx->sp;
                spy = apy->x.rp->precsym;
                if( spy==0 || spx->prec<0 || spy->prec<0 ){
                        /* Not enough precedence information. */
                        apy->type = SRCONFLICT;
                        errcnt++;
                }else if( spx->prec>spy->prec ){    /* higher precedence wins */
                        apy->type = RD_RESOLVED;
                }else if( spx->prec<spy->prec ){
                        apx->type = SH_RESOLVED;
                }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use 
operator */
                        apy->type = RD_RESOLVED;                             /* 
associativity */
                }else if( spx->prec==spy->prec && spx->assoc==LEFT ){  /* to 
break tie */
                        apx->type = SH_RESOLVED;
                }else if( spx->prec==spy->prec && spx->assoc==NONE) {   /* MY 
CHANGE HERE */
                        apx->type = ERROR;
                }else{
                        assert( spx->prec==spy->prec && spx->assoc==NONE );
                        apy->type = SRCONFLICT;
                        errcnt++;
                }

I’m hoping this proves useful to you. I am enjoying the tool. It is fast, 
straightforward, and easy to use.

Thank you,
Alexander Barrentine

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to