Skip to content

Commit

Permalink
Improve error message for start declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
0x2a-42 committed Dec 27, 2024
1 parent 0ab861e commit 2db979b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 15 deletions.
9 changes: 9 additions & 0 deletions src/frontend/diag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub const REDEF_OPEN_NODE: &str = "E022";
pub const UNDEF_CLOSE_NODE: &str = "E023";
pub const INVALID_CLOSE_NODE: &str = "E024";
pub const CREATE_RULE_NODE_LEFT_REC: &str = "E025";
pub const EXPECTED_RULE: &str = "E026";

pub const UNUSED_RULE: &str = "W001";
pub const UNUSED_TOKEN: &str = "W002";
Expand Down Expand Up @@ -63,6 +64,7 @@ pub trait LanguageErrors {
fn create_rule_node_left_rec(span: &Span) -> Self;
fn unused_node_marker(span: &Span) -> Self;
fn redundant_elision(span: &Span) -> Self;
fn expected_rule(span: &Span) -> Self;
}

impl LanguageErrors for Diagnostic {
Expand Down Expand Up @@ -341,4 +343,11 @@ impl LanguageErrors for Diagnostic {
.with_message("node elision is redundant")
.with_labels(vec![Label::primary((), span.clone())])
}

fn expected_rule(span: &Span) -> Self {
Diagnostic::error()
.with_code(EXPECTED_RULE)
.with_message("expected rule")
.with_labels(vec![Label::primary((), span.clone())])
}
}
30 changes: 15 additions & 15 deletions src/frontend/sema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,16 @@ impl<'a> GeneralCheck<'a> {
&mut self,
name: &'a str,
rule_binding: bool,
span: Span,
span: &Span,
diags: &mut Vec<Diagnostic>,
) -> Option<NodeRef> {
self.symbol_table
.get(name)
.or_else(|| {
if rule_binding {
diags.push(Diagnostic::undefined_rule(&span, name));
diags.push(Diagnostic::undefined_rule(span, name));
} else {
diags.push(Diagnostic::undefined_token(&span, name));
diags.push(Diagnostic::undefined_token(span, name));
}
None
})
Expand Down Expand Up @@ -288,12 +288,14 @@ impl<'a> GeneralCheck<'a> {
diags: &mut Vec<Diagnostic>,
sema: &mut SemanticData<'a>,
) {
if let Some(rule_decl) = start_decl
.rule_name(cst)
.and_then(|(name, name_span)| self.get_symbol_binding(name, true, name_span, diags))
.and_then(|node| RuleDecl::cast(cst, node))
{
sema.start = Some(rule_decl);
if let Some((name, name_span)) = start_decl.rule_name(cst) {
if let Some(node) = self.get_symbol_binding(name, true, &name_span, diags) {
if let Some(rule_decl) = RuleDecl::cast(cst, node) {
sema.start = Some(rule_decl);
} else {
diags.push(Diagnostic::expected_rule(&name_span));
}
}
}
}
fn check_right_decl(
Expand All @@ -304,7 +306,7 @@ impl<'a> GeneralCheck<'a> {
sema: &mut SemanticData<'a>,
) {
right_decl.token_names(cst, |(name, name_span)| {
if let Some(node) = self.get_symbol_binding(name, false, name_span.clone(), diags) {
if let Some(node) = self.get_symbol_binding(name, false, &name_span, diags) {
if let Some(token_decl) = TokenDecl::cast(cst, node) {
if let Some((name, _)) = token_decl.name(cst) {
if sema.right_associative.contains(&name) {
Expand All @@ -327,7 +329,7 @@ impl<'a> GeneralCheck<'a> {
sema: &mut SemanticData<'a>,
) {
skip_decl.token_names(cst, |(name, name_span)| {
if let Some(node) = self.get_symbol_binding(name, false, name_span.clone(), diags) {
if let Some(node) = self.get_symbol_binding(name, false, &name_span, diags) {
if let Some(token_decl) = TokenDecl::cast(cst, node) {
if sema.skipped.contains(&token_decl) {
diags.push(Diagnostic::redefine_as_skipped(&name_span));
Expand Down Expand Up @@ -398,7 +400,7 @@ impl<'a> GeneralCheck<'a> {
if let Some((name, name_span)) = regex.value(cst) {
let rule_binding = name.starts_with(|c: char| c.is_lowercase());
if let Some(decl) =
self.get_symbol_binding(name, rule_binding, name_span.clone(), diags)
self.get_symbol_binding(name, rule_binding, &name_span, diags)
{
if let Some(token) = TokenDecl::cast(cst, decl) {
if sema.skipped.contains(&token) {
Expand All @@ -412,9 +414,7 @@ impl<'a> GeneralCheck<'a> {
}
Regex::Symbol(regex) => {
if let Some((name, name_span)) = regex.value(cst) {
if let Some(decl) =
self.get_symbol_binding(name, false, name_span.clone(), diags)
{
if let Some(decl) = self.get_symbol_binding(name, false, &name_span, diags) {
if let Some(token) = TokenDecl::cast(cst, decl) {
if sema.skipped.contains(&token) {
diags.push(Diagnostic::used_skipped(&name_span));
Expand Down

0 comments on commit 2db979b

Please sign in to comment.