ATN: Handle empty, read-only, nextTokenWithinRule

ATN::nextTokens(ATNState* s) updates s->nextTokenWithinRule if the
IntervalSet is empty, and then sets it to be read only. However, if the
updated IntervalSet value was also empty, it becomes a read-only empty
set, causing an exception on a second call on the same state.

This was exposed a change I made to make IntervalSet::operator=()
respect the _readonly flag. (Which in turn was found by compiling with a
high warningly level.)

The approach in this update is to perform the update if the updated
value is not empty or if the current value is not read only. This
preserves the previous behaviour of creating a read-only empty set and
working on subsequent calls. It will throw on an attempt to update a
read-only value, where previously the read-only value would be silently
discarded and set to updatable.
This commit is contained in:
Jan Martin Mikkelsen 2017-06-11 09:53:47 +10:00
parent eb02a05efb
commit 4a359c1831
1 changed files with 5 additions and 2 deletions

View File

@ -89,8 +89,11 @@ misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContext *ctx) const {
misc::IntervalSet& ATN::nextTokens(ATNState *s) const {
if (s->nextTokenWithinRule.isEmpty()) {
s->nextTokenWithinRule = nextTokens(s, nullptr);
s->nextTokenWithinRule.setReadOnly(true);
auto candidate = nextTokens(s, nullptr);
if (!candidate.isEmpty() || !s->nextTokenWithinRule.isReadOnly()) {
s->nextTokenWithinRule = candidate;
s->nextTokenWithinRule.setReadOnly(true);
}
}
return s->nextTokenWithinRule;
}