-
Notifications
You must be signed in to change notification settings - Fork 201
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
Previous Token Information on Errors. #613
Comments
For anyone having the same issue, the workaround requires to create a new token, as the token location properties are read-only. Use: chevrotain.createTokenInstance(chevrotain.EOF, "", startOffset, endOffset, startLine, endLine, startColumn, endColumn); |
the EOF does not really have a location. https://github.com/SAP/chevrotain/blob/master/src/parse/parser_public.ts#L3083-L3085 // old code
throw this.SAVE_ERROR(new exceptions.EarlyExitException(msg, this.LA(1))
// new code, LA(0) will return the previously successfully parsed Token.
throw this.SAVE_ERROR(new exceptions.EarlyExitException(msg, this.LA(1), this.LA(0)) Of course the class of the EarlyExitError will also have to modified to add the new property. |
The one edge case is what if the error is for a completely empty text input. So that edge case would have to be tested. |
This seems fairly trivial to implement, So I'll happily accept pull requests for this 😄 |
That is a good solution. I will add the changes today and send you a pull request. The edge case will be no problem for the linter, as VS Code will put the error marker at the beginning of the file if the location is missing. |
We still need to check the edge case does not cause some weird runtime exception for Chevrotain. |
ok, so I can simply check if LA(0) is null, right? If that is the case, I will use LA(1) twice. Or should I additionally check with the tokenMatcher if LA(1) is EOF? |
The cleanest solution would be up upgrade LA to handle this. protected LA(howMuch: number): IToken {
// Maybe add another check here that:
// currIdx + HowMuch > 0
if (this.tokVectorLength <= this.currIdx + howMuch) {
return END_OF_FILE
} else {
return this.tokVector[this.currIdx + howMuch]
}
} The problem is that it might actually cause a slight performance regression as LA(x) is used a-lot. But they are not working 100% as i've made a lot of breaking changes in the upcoming 1.0.0 version. |
Sorry, I am not sure I understand your last comment. Our edge case is that |
this.currIdx starts at -1
and the If condition would be:
I know its confusing 😿 |
Ah ok, now I get it. Thank you for the explanation. |
How about this: if (this.tokVectorLength === 0 || this.tokVectorLength <= this.currIdx + howMuch) {
return END_OF_FILE
} else {
return this.tokVector[this.currIdx + howMuch]
} |
Mhm, while this would work in the edge case it might still cause problems if one calls LA(0) and you probably want a general solution. So I will simply do what you proposed. Sorry for thinking out loud. |
ok, last question: What should happen if |
I think it is still correct that it is EOF, just that the EOF is also the Start Of File, for an "empty" file. I don't see a good alternative, creating a SOF virtual seems redundant, and returning null/undefined |
Today I finally managed to update Chevrotain in my parser to 2.0.1 and remove the workaround I posted above. I made some tests and realized that the same issue can occur in MismatchedTokenException and NoViableAltException as well. I previously thought that error.token can only be an instance of EOF if the error is an EarlyExitException, but this is not the case. MismatchedTokenException and NoViableAltException can also have EOF as their token and will not contain any location information in these cases. I have not been able to produce such a case with a NotAllInputParsedException but maybe the same issue can occur there. So I guess it would make sense to add error.previousToken for all types of exceptions, right? |
Sorry for the delay, I knew I missed replying somewhere 😄 NotAllInputParsedException can never have EOF as its token as the condition to throw it requires that Anyhow it makes sense to expend whatever solution you implemented to those other Exceptions types as well... |
Hi, have you added the previousToken information for MismatchedTokenException and NoViableAltException? Or did you expect a pull request from me and closed the issue because I did not send you one (to be honest, I forgot this issue)? |
Actually I was pruning the backlog and thought this issue was closed as I did not re-read the whole conversation. I will re-open it until once of us will get around to finishing it. 😄 |
…MismatchedTokenException
…MismatchedTokenException
Hi, for my VS Code linter I need the exact token locations for every parser error. If the error is an EarlyExitException and the token is of type chevrotain.EOF, the location properties of the token are all set to null. As a workaround I can check for this case in my linter and replace the location info in the error with the endLine and endColumn of the last token. But it would be nice if Chevrotain could do this for me.
The text was updated successfully, but these errors were encountered: