chevrotain
chevrotain copied to clipboard
Custom User Defined Syntax Errors
Example
$.RULE("formalParameterList", () => {
let foundRestArg = false
$.MANY_SEP({
SEP: tokens.Comma,
DEF: () => {
$.MANY2(() => {
$.SUBRULE($.variableModifier)
})
$.SUBRULE($.typeType)
$.OPTION(() => {
$.CONSUME(tokens.DotDotDot)
foundRestArg = true
})
$.SUBRULE($.variableDeclaratorId)
if (foundRestArg && $.LA(1).tokenType === tokens.Comma) {
// This will fail at runtime now!
throw this.SAVE_ERROR(new Error("oops, can't have additional params after rest param"))
}
}
})
})
Requires a slight modification to the SAVE_ERROR code to avoid throwing a new error if the error is not a pre-known "RecognizerError"
Initiated due to discussion in: https://github.com/SAP/chevrotain/issues/645
Just a note on this: I'm not sure a throw
call is the best here.
Namely, if you're in some kind of "linting" scenario, you won't necessarily produce a single error. You might want to recover, but add an error to the stack. I guess this will work as long as throw
is not a requirement, and you can just do
if (foundRestArg && $.LA(1).tokenType === tokens.Comma) {
this.SAVE_ERROR(new Error("oops, can't have additional params after rest param"))
}
If it is a syntax error it needs to throw and the Parser will auto recover if errorRecovery is enabled, That is what happens for example in MisMatchTokenError
- https://github.com/SAP/chevrotain/blob/master/packages/chevrotain/src/parse/parser/traits/recognizer_engine.ts#L936-L938
If it is a linting error which does not affect parsing flow it could be saved in a separate data structure, preferably during a post parsing step (e.g CST Visitor).
Although there could be some kind of mish-mash that seems partially syntax and partially semantics related. in that case you could still use SAVE_ERROR without throwing the result.
- https://github.com/SAP/chevrotain/blob/master/packages/chevrotain/src/parse/parser/traits/error_handler.ts#L35-L51
The (minor) problem that this issue needs to resolve is that the SAVE_ERROR API:
- Is not public
- Does not work when provided with a new Custom Error type that it does not recognize.