Skip to main content

antlr4_runtime/
errors.rs

1use crate::recognizer::Recognizer;
2use crate::token::{TokenId, TokenView};
3use thiserror::Error;
4
5#[derive(Debug, Error, Clone, Eq, PartialEq)]
6pub enum AntlrError {
7    #[error("mismatched input: expected {expected}, found {found}")]
8    MismatchedInput { expected: String, found: String },
9    #[error("no viable alternative at input {input}")]
10    NoViableAlternative { input: String },
11    #[error("lexer error at {line}:{column}: {message}")]
12    LexerError {
13        line: usize,
14        column: usize,
15        message: String,
16    },
17    #[error("parser error at {line}:{column}: {message}")]
18    ParserError {
19        line: usize,
20        column: usize,
21        message: String,
22        /// Token the error is anchored to, when one exists. The anchor must
23        /// be captured where the error is built: prediction restores the
24        /// input cursor, so the current lookahead at reporting time is not
25        /// necessarily the offending token (`no viable alternative` anchors
26        /// at the error index while the cursor sits at the decision start).
27        offending: Option<TokenId>,
28    },
29    #[error("unsupported runtime feature: {0}")]
30    Unsupported(String),
31}
32
33/// Receives recognizer diagnostics.
34///
35/// Listeners registered through [`Recognizer::add_error_listener`] must be
36/// [`Send`] and work with every recognizer type. Implement the trait
37/// generically, as [`ConsoleErrorListener`] does, when a listener will be
38/// registered.
39pub trait ErrorListener<R: Recognizer + ?Sized> {
40    /// `offending` carries the token the diagnostic points at, matching
41    /// ANTLR's `syntaxError(recognizer, offendingSymbol, ...)`. It is `None`
42    /// for lexer errors (no token was produced) and for diagnostics that are
43    /// not anchored to a specific token.
44    #[allow(clippy::too_many_arguments)] // mirrors ANTLR's canonical syntaxError signature
45    fn syntax_error(
46        &mut self,
47        recognizer: &R,
48        offending: Option<TokenView<'_>>,
49        line: usize,
50        column: usize,
51        message: &str,
52        error: Option<&AntlrError>,
53    );
54}
55
56#[derive(Debug, Default)]
57pub struct ConsoleErrorListener;
58
59impl<R: Recognizer + ?Sized> ErrorListener<R> for ConsoleErrorListener {
60    #[allow(clippy::print_stderr)]
61    fn syntax_error(
62        &mut self,
63        _recognizer: &R,
64        _offending: Option<TokenView<'_>>,
65        line: usize,
66        column: usize,
67        message: &str,
68        _error: Option<&AntlrError>,
69    ) {
70        eprintln!("line {line}:{column} {message}");
71    }
72}