From cf65687337a4bf3427cf7ddb6acbd1d6f4548770 Mon Sep 17 00:00:00 2001 From: Natapat Samutpong Date: Sun, 6 Mar 2022 22:50:23 +0700 Subject: [PATCH] error reporting with ariadne --- Cargo.lock | 3 +- crates/main/Cargo.toml | 4 +- crates/main/src/main.rs | 87 ++++++++++++++++++++++++++++++++++------ crates/main/src/util.rs | 4 +- crates/parser/Cargo.toml | 3 +- 5 files changed, 83 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7bcf3f..b512b86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,8 @@ dependencies = [ name = "hycron" version = "0.1.0" dependencies = [ + "ariadne", + "chumsky", "clap", "lexer", "parser", @@ -205,7 +207,6 @@ dependencies = [ name = "parser" version = "0.1.0" dependencies = [ - "ariadne", "chumsky", "lexer", ] diff --git a/crates/main/Cargo.toml b/crates/main/Cargo.toml index e64d976..c83ea9f 100644 --- a/crates/main/Cargo.toml +++ b/crates/main/Cargo.toml @@ -8,4 +8,6 @@ edition = "2021" [dependencies] clap = { version = "3.0.14", features = ["derive"] } lexer = { path = "../lexer" } -parser = { path = "../parser" } \ No newline at end of file +parser = { path = "../parser" } +chumsky = "0.8.0" +ariadne = "0.1.5" \ No newline at end of file diff --git a/crates/main/src/main.rs b/crates/main/src/main.rs index b748c2a..0d24dc4 100644 --- a/crates/main/src/main.rs +++ b/crates/main/src/main.rs @@ -1,6 +1,7 @@ use std::fs; use clap::Parser as ArgParser; +use ariadne::{Report, ReportKind, Label, Source, Color, Fmt}; use lexer::lex; use parser::parse; @@ -22,22 +23,84 @@ fn main() { // Lex the file. let (tokens, lex_error) = lex(src.clone()); - - if lex_error.is_empty() { - log(0, "Lexing successful."); + let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count()); - let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count()); + lex_error.into_iter() + .map(|e| e.map(|e| e.to_string())) + .chain(parse_error.into_iter().map(|e| e.map(|tok| tok.to_string()))) + .for_each(|e| { + let report = Report::build(ReportKind::Error, (), e.span().start); - if parse_error.is_empty() { + let report = match e.reason() { + chumsky::error::SimpleReason::Unclosed { span, delimiter } => report + .with_message(format!( + "Unclosed delimiter {}", + delimiter.fg(Color::Yellow) + )) + .with_label( + Label::new(span.clone()) + .with_message(format!( + "Expected closing delimiter {}", + delimiter.fg(Color::Yellow) + )) + .with_color(Color::Yellow) + ) + .with_label( + Label::new(e.span()) + .with_message(format!( + "Must be closed before this {}", + e.found() + .unwrap_or(&"end of file".to_string()) + .fg(Color::Red) + )) + .with_color(Color::Red) + ), + + chumsky::error::SimpleReason::Unexpected => report + .with_message(format!( + "{}, expected {}", + + if e.found().is_some() {"Unexpected token in input" } + else { "Unexpected end of input" }, + + if e.expected().len() == 0 { "something else".to_string().fg(Color::Green) } + else { + e.expected() + .map(|expected| match expected { + Some(expected) => expected.to_string(), + None => "end of input".to_string() + }) + .collect::>() + .join(", ") + .fg(Color::Green) + } + )) + .with_label( + Label::new(e.span()) + .with_message(format!( + "Unexpected token {}", + e.found() + .unwrap_or(&"EOF".to_string()) + .fg(Color::Red) + )) + .with_color(Color::Red) + ), + _ => { + println!("{:?}", e); + todo!(); + } + }; + + report.finish().print(Source::from(&src)).unwrap(); + }); + + match ast { + Some(ast) => { println!("{:#?}", ast); - log(0, "Parsing successful."); - } else { - println!("{:#?}", parse_error); - log(2, "Parsing failed."); + }, + None => { + log(2, "Failed to parse."); } - } else { - println!("{:#?}", lex_error); - log(2, "Lexing failed."); } } } diff --git a/crates/main/src/util.rs b/crates/main/src/util.rs index d4a82a1..026a6da 100644 --- a/crates/main/src/util.rs +++ b/crates/main/src/util.rs @@ -3,8 +3,8 @@ use std::fmt::Display; pub fn log(level: i8, msg: T) { match level { 0 => println!("\x1b[92m[INFO]\x1b[0m {}", msg), - 1 => println!("[WARN] {}", msg), - 2 => println!("[ERRO] {}", msg), + 1 => println!("\x1b[93m[WARN]\x1b[0m {}", msg), + 2 => println!("\x1b[91m[ERRS]\x1b[0m {}", msg), _ => println!("{}", msg), } } \ No newline at end of file diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 5d7b331..ef01deb 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -7,5 +7,4 @@ edition = "2021" [dependencies] lexer = { path = "../lexer" } -chumsky = "0.8.0" -ariadne = "0.1.5" \ No newline at end of file +chumsky = "0.8.0" \ No newline at end of file