[antlr-interest] Bug in Generated Parser?

Terence Parr parrt at cs.usfca.edu
Thu Jul 17 14:10:08 PDT 2008


On Jul 17, 2008, at 2:05 PM, Gavin Lambert wrote:

> At 00:51 18/07/2008, Johannes Luber wrote:
> >> I'm seeing different behavior running my parser with a syntax
> >> error the second time run. I've tracked it down to where I
> >> believe the problem is, located in BaseRecognizer.cs. The
> >> "follow.Remove( Token.EOR_TOKEN_TYPE )" logic is being
> >> called, which modifies the state of the static readonly
> >> BitSet object found on the parser. The problem with that
> >> is that even though I am creating a completely different
> >> parser instance, the static variable has been altered for
> >> as long as the assembly is in memory. I've copied a simple
> >> program to illustrate the problem at the bottom of this mail.
> >
> >I haven't heard of it yet, but it's a Java target problem, too,
> >so Ter has to say, if removing the static modifier for the
> >BitSet variables in the parser is enough and doesn't affect
> >anything else.
>
> I don't think that's sufficient -- after all, a single instance  
> might be re-used, or the rule-path followed might query that  
> structure again (expecting it to be in its unmodified state).

I think i saw this...seems I forced it to dup after I found this...

> Read-only variables should never be modified.  Any code that is  
> doing so is clearly erroneous.  (Perhaps it should be modifying a  
> clone of the object instead of the original?)
>

yes, a clone.  Ok, looks like mine is ok:

     protected BitSet combineFollows(boolean exact) {
         int top = state._fsp;
         BitSet followSet = new BitSet();
         for (int i=top; i>=0; i--) {
             BitSet localFollowSet = (BitSet)state.following[i];
             /*
             System.out.println("local follow depth "+i+"="+
                                 
localFollowSet.toString(getTokenNames())+")");
              */
             followSet.orInPlace(localFollowSet);
             if ( exact ) {
                 // can we see end of rule?
                 if ( localFollowSet.member(Token.EOR_TOKEN_TYPE) ) {
                     // Only leave EOR in set if at top (start rule);  
this lets
                     // us know if have to include follow(start rule);  
i.e., EOF
                     if ( i>0 ) {
                         followSet.remove(Token.EOR_TOKEN_TYPE);
                     }
                 }
                 else { // can't see end of rule, quit
                     break;
                 }
             }
         }
         return followSet;
     }

Note that it is creating a new BitSet at the start...it is removing  
only from that set.

Ter


More information about the antlr-interest mailing list