https://lalrpop.github.io/lalrpop/lexer_tutorial/006_error_recovery_custom_lexer.html
Features described in Error recovery work well with the custom lexer, however error recovery only supports recovering from parser errors - not lexer errors. This page shows an approach to recover from lexer errors.
MST -- 错误恢复中描述的功能适用于自定义词法分析器,但错误恢复仅支持从解析器错误中恢复,而不支持从词法分析器错误中恢复。本页介绍了一种从词法分析器错误中恢复的方法。
GPT -- “在错误恢复部分中,所描述的特性与自定义词法分析器配合良好,但错误恢复仅支持从解析器错误中恢复——不支持从词法分析器错误中恢复。本页面展示了一种从词法分析器错误中恢复的方法。”
Enable error recovery:
MST -- 启用错误恢复:
GPT -- “启用错误恢复:”
use lalrpop_util::ErrorRecovery;
- grammar<'err>(errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, &'static str>>);
+ grammar<'err>(errors: &'err mut Vec<ErrorRecovery<usize, Token, LexicalError>>);
Now error recovery will work for parser errors, however if your lexer encounters an unexpected token, that's a lexer error, not a parser error so the parser is unable to recover from it.
MST -- 现在,错误恢复将适用于解析器错误,但是,如果您的词法分析器遇到意外的标记,那是词法分析器错误,而不是解析器错误,因此解析器无法从中恢复。
GPT -- “现在,错误恢复将适用于解析器错误,但是如果词法分析器遇到意外的令牌,那是词法错误,而不是解析器错误,因此解析器无法从中恢复。”
print (a - $);
// Err(User { error: InvalidToken })
It's caused by the inconsistency in the lexer stream, as lalrpop parser always expects a normal token stream. To fix this, you need to add a workaround in the lexer part to process the "error recovery" inside the lexer, for example
MST -- 这是由 lexer 流中的不一致引起的,因为 lalrpop 解析器始终需要正常的令牌流。要解决此问题,您需要在词法分析器部分中添加解决方法,以处理词法分析器内的“错误恢复”,例如
GPT -- “这是由于词法分析器流的不一致性引起的,因为 LALRPOP 解析器始终期望一个正常的令牌流。为了解决这个问题,你需要在词法分析器部分添加一个变通方法,在词法分析器内部处理‘错误恢复’,例如:”
impl<'input> Iterator for Lexer<'input> {
type Item = Spanned<Token, usize, LexicalError>;
fn next(&mut self) -> Option<Self::Item> {
self.token_stream
.next()
- .map(|(token, span)| Ok((span.start, token?, span.end)))
+ .map(|(token, span)|
+ match token {
+ Ok(token) => Ok((span.start, token, span.end)),
+ Err(_) => Ok((span.start, Token::Error, span.end)),
+ // or specify your lexical error to parse error
+ }
+ )
}
}
and then put a new member into Token enum to represent the error token (or your custom error type).
MST -- 然后将新成员放入 Token 枚举中以表示错误令牌(或您的自定义错误类型)。
GPT -- “然后,在
Token
枚举中添加一个新成员来表示错误令牌(或你自定义的错误类型)。”
pub enum Token {
//...
// Dont forget the comma
+ Error
}
Like NaN is a number in JavaScript, we have now an Token::Error which is a token in our lexer. This token can be passed to the parser, but if it is not used in the parser grammar, will not parse. That transforms the lexer error into a recoverable parser error allowing you to have error recovery in this case.
MST -- 就像 NaN 在 JavaScript 中是一个数字一样,我们现在有一个 Token::Error ,它是词法分析器中的一个标记。此令牌可以传递给解析器,但如果它未在解析器语法中使用,则不会解析。这会将词法分析器错误转换为可恢复的解析器错误,从而允许您在这种情况下进行错误恢复。
GPT -- “就像 NaN 是 JavaScript 中的一个数字一样,我们现在有了
Token::Error
,它是我们词法分析器中的一个令牌。这个令牌可以传递给解析器,但如果它没有在解析器的语法中被使用,就不会被解析。这样就将词法分析器错误转化为可恢复的解析器错误,从而在这种情况下实现错误恢复。”
Also, you might need to custom your own error, visit the section on fallible actions for details.
MST -- 此外,您可能需要自定义自己的错误,有关详细信息,请访问易出错操作部分。
GPT -- “另外,你可能需要自定义自己的错误,详细信息请参阅关于可失败操作的部分。”
! => {
let error = ErrorRecovery {
error: ParseError::User {
error: LexicalError::SomeCustomError,
},
dropped_tokens: Vec::new(), // or specify the dropped tokens
};
errors.push(error);
Expression::Error
}
标签:解析器,recovery,错误,lexer,分析器,词法,自定义词,error
From: https://www.cnblogs.com/Tifahfyf/p/18653762