[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