Skip to content

Comment contradicts code (in all run-times)? #2172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
niccroad opened this issue Dec 18, 2017 · 10 comments
Closed

Comment contradicts code (in all run-times)? #2172

niccroad opened this issue Dec 18, 2017 · 10 comments

Comments

@niccroad
Copy link
Contributor

niccroad commented Dec 18, 2017

In this function of PredictionContext.

public static PredictionContext mergeRoot(SingletonPredictionContext a,
											  SingletonPredictionContext b,
											  boolean rootIsWildcard)
	{
		if ( rootIsWildcard ) {
			if ( a == EMPTY ) return EMPTY;  // * + b = *
			if ( b == EMPTY ) return EMPTY;  // a + * = *
		}
		else {
			if ( a == EMPTY && b == EMPTY ) return EMPTY; // $ + $ = $
			if ( a == EMPTY ) { // $ + x = [$,x]
				int[] payloads = {b.returnState, EMPTY_RETURN_STATE};
				PredictionContext[] parents = {b.parent, null};
				PredictionContext joined =
					new ArrayPredictionContext(parents, payloads);
				return joined;
			}
			if ( b == EMPTY ) { // x + $ = [$,x] ($ is always first if present)
				int[] payloads = {a.returnState, EMPTY_RETURN_STATE};
				PredictionContext[] parents = {a.parent, null};
				PredictionContext joined =
					new ArrayPredictionContext(parents, payloads);
				return joined;
			}
		}
		return null;
	}

The comments // $ + x = [$,x]
and more explicitly // x + $ = [$,x] ($ is always first if present)

Seem to contradict the implementation. This was done 6 years ago by @parrt.
Should the order in the comments not be [x,$], ($ is always second if present)?

@parrt
Copy link
Member

parrt commented Dec 19, 2017

Indeed that looks weird. @sharwell note that we create

int[] payloads = {b.returnState, EMPTY_RETURN_STATE};
...
PredictionContext joined = new ArrayPredictionContext(parents, payloads);

but ArrayPredictionContext.isEmpty() tests

// since EMPTY_RETURN_STATE can only appear in the last position, we
// don't need to verify that size==1
return returnStates[0]==EMPTY_RETURN_STATE;

That seems like a glaring problem but we've not seen any weird bugs have we?

@parrt
Copy link
Member

parrt commented Dec 19, 2017

Actually, now I see something else in PredictionContext:

public boolean hasEmptyPath() {
	// since EMPTY_RETURN_STATE can only appear in the last position, we check last one
	return getReturnState(size() - 1) == EMPTY_RETURN_STATE;
}

@sharwell
Copy link
Member

sharwell commented Dec 19, 2017

The implementations of isEmpty and hasEmptyPath seem correct.

  • For isEmpty: the first item is EMPTY_RETURN_STATE (explicit check) plus only the last item can be EMPTY_RETURN_STATE (invariant) implies size is 1
  • For hasEmptyPath: The last item is checked by reading size()

So this is just a bug to update the comment in code?

@parrt
Copy link
Member

parrt commented Dec 19, 2017

Actually, it looks like a bug. Test for ArrayPredictionContext.isEmpty expects EMPTY_RETURN_STATE in position 0 but mergeRoot() is putting it at position 1

@sharwell
Copy link
Member

sharwell commented Dec 19, 2017

Actually, it looks like a bug. Test for ArrayPredictionContext.isEmpty expects EMPTY_RETURN_STATE in position 0 but mergeRoot() is putting it at position 1

The result of mergeRoot is not empty. Updated my previous comment too.

@parrt
Copy link
Member

parrt commented Dec 19, 2017

Doesn't it create an array context with int[] payloads = {b.returnState, EMPTY_RETURN_STATE}; putting the empty in 2nd position? Right. not completely empty but looks like we test for a different condition.

@sharwell
Copy link
Member

isEmpty is a combination of (hasEmptyPath) and (size() == 1). The "weird" indexing is an optimization leveraging an invariant of the data structure to eliminate a call to size() on a hot path.

@parrt
Copy link
Member

parrt commented Dec 19, 2017

interesting. ok, so is the "fix" just changing this comment?

// x + $ = [$,x] ($ is always first if present)

to

// x + $ = [x,$] ($ is always last if present)

@sharwell
Copy link
Member

interesting. ok, so is the "fix" just changing this comment?

I believe that is correct.

@parrt
Copy link
Member

parrt commented Dec 19, 2017

ok, cool. thanks!

@parrt parrt added code-gen and removed code-gen labels Dec 19, 2017
parrt added a commit to parrt/antlr4 that referenced this issue Dec 19, 2017
@parrt parrt closed this as completed in 74779f3 Dec 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants