diff --git a/components/dada-ir/src/diagnostic.rs b/components/dada-ir/src/diagnostic.rs index db2e9f7b..68ebdc74 100644 --- a/components/dada-ir/src/diagnostic.rs +++ b/components/dada-ir/src/diagnostic.rs @@ -13,6 +13,9 @@ pub struct ErrorReported; #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[non_exhaustive] pub struct Diagnostic { + /// This is only used for testing the reference grammar. + /// If it's true it means that the reference grammar should also emit an error. + pub is_grammar_error: bool, pub severity: Severity, pub span: FileSpan, pub message: String, @@ -54,6 +57,15 @@ macro_rules! error { } } +/// Convenience macro for avoiding `format!` +/// Use this when the error should also be emitted by the reference grammar +#[macro_export] +macro_rules! grammar_error { + ($span:expr, $($message:tt)*) => { + $crate::diagnostic::Diagnostic::builder($crate::diagnostic::Severity::Error, $span, format!($($message)*)).is_grammar_error() + } +} + /// Convenience macro for avoiding `format!` #[macro_export] macro_rules! warning { @@ -119,6 +131,8 @@ pub struct DiagnosticBuilder { /// label ("here") when the diagnostic is emitted. Set to false /// if user adds an explicit primary label or calls [`Self::skip_primary_label`]. add_primary_label: bool, + + is_grammar_error: bool, } impl DiagnosticBuilder { @@ -130,9 +144,16 @@ impl DiagnosticBuilder { labels: vec![], children: vec![], add_primary_label: true, + is_grammar_error: false, } } + #[must_use = "you have not emitted the diagnostic"] + pub fn is_grammar_error(mut self) -> Self { + self.is_grammar_error = true; + self + } + /// Replaces the "primary label", which is always placed on the source /// of the diagnostic. The default primary label, if nothing else is given, /// is just "here". @@ -186,6 +207,7 @@ impl DiagnosticBuilder { } Diagnostic { + is_grammar_error: self.is_grammar_error, severity: self.severity, span: self.span, message: self.message, diff --git a/components/dada-lex/src/lex.rs b/components/dada-lex/src/lex.rs index 53e7edf6..a2b0f946 100644 --- a/components/dada-lex/src/lex.rs +++ b/components/dada-lex/src/lex.rs @@ -216,7 +216,7 @@ where .map(|pair| pair.0) .unwrap_or(self.file_len), ); - dada_ir::error!( + dada_ir::grammar_error!( Span { start: ch_offset, end, diff --git a/components/dada-parse/src/parser.rs b/components/dada-parse/src/parser.rs index d73f3a71..8eebc8a0 100644 --- a/components/dada-parse/src/parser.rs +++ b/components/dada-parse/src/parser.rs @@ -198,7 +198,7 @@ impl<'me> Parser<'me> { } fn error(&self, span: Span, message: impl ToString) -> DiagnosticBuilder { - dada_ir::error!(span.in_file(self.input_file), "{}", message.to_string()) + dada_ir::grammar_error!(span.in_file(self.input_file), "{}", message.to_string()) } } diff --git a/components/dada-parse/src/parser/items.rs b/components/dada-parse/src/parser/items.rs index 60db98bc..772ca3ae 100644 --- a/components/dada-parse/src/parser/items.rs +++ b/components/dada-parse/src/parser/items.rs @@ -32,7 +32,8 @@ impl<'db> Parser<'db> { } else { let span = self.tokens.last_span(); self.tokens.consume(); - dada_ir::error!(span.in_file(self.input_file), "unexpected token").emit(self.db); + dada_ir::grammar_error!(span.in_file(self.input_file), "unexpected token") + .emit(self.db); } }