lang: improve and simplify error handling and storage

fixes wrong error ordering with errors using `forward_parents`.
This commit is contained in:
Schrottkatze 2024-06-03 10:53:59 +02:00
parent ed151c2e3c
commit f6da90a354
Signed by: schrottkatze
SSH key fingerprint: SHA256:hXb3t1vINBFCiDCmhRABHX5ocdbLiKyCdKI4HK2Rbbc
8 changed files with 110 additions and 42 deletions

View file

@ -1,6 +1,6 @@
use crate::lst_parser::syntax_kind::SyntaxKind;
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum SyntaxError {
Expected(Vec<SyntaxKind>),
PipelineNeedsSink,

View file

@ -1,22 +1,69 @@
use crate::lst_parser::syntax_kind::SyntaxKind;
use super::error::SyntaxError;
#[derive(Debug)]
pub enum Event {
Start {
kind: SyntaxKind,
kind: NodeKind,
forward_parent: Option<usize>,
},
Finish,
Eat {
count: usize,
},
Error,
}
#[derive(Debug, Clone, PartialEq)]
pub enum NodeKind {
Syntax(SyntaxKind),
Error(SyntaxError),
}
impl NodeKind {
pub fn is_syntax(&self) -> bool {
matches!(self, Self::Syntax(_))
}
pub fn is_error(&self) -> bool {
matches!(self, Self::Error(_))
}
}
impl From<SyntaxKind> for NodeKind {
fn from(value: SyntaxKind) -> Self {
NodeKind::Syntax(value)
}
}
impl From<SyntaxError> for NodeKind {
fn from(value: SyntaxError) -> Self {
NodeKind::Error(value)
}
}
impl PartialEq<SyntaxKind> for NodeKind {
fn eq(&self, other: &SyntaxKind) -> bool {
match self {
NodeKind::Syntax(s) => s == other,
NodeKind::Error(_) => false,
}
}
}
impl PartialEq<SyntaxError> for NodeKind {
fn eq(&self, other: &SyntaxError) -> bool {
match self {
NodeKind::Syntax(_) => false,
NodeKind::Error(e) => e == other,
}
}
}
impl Event {
pub(crate) fn tombstone() -> Self {
Self::Start {
kind: SyntaxKind::TOMBSTONE,
kind: SyntaxKind::TOMBSTONE.into(),
forward_parent: None,
}
}

View file

@ -35,7 +35,7 @@ pub fn parenthesized_expr(p: &mut Parser) -> Option<CompletedMarker> {
let par_expr = p.start("parenthesized");
expression(p, false);
if !p.eat(R_PAREN) {
return Some(par_expr.complete_err(p, SyntaxError::Expected(vec![R_PAREN])));
return Some(par_expr.error(p, SyntaxError::Expected(vec![R_PAREN])));
}
return Some(par_expr.complete(p, PARENTHESIZED_EXPR));

View file

@ -21,7 +21,7 @@ pub fn vec_matrix_list(p: &mut Parser) -> CompletedMarker {
start.complete(p, LIST)
} else {
row_start.abandon(p);
start.complete_err(p, SyntaxError::Expected(vec![EXPR, R_BRACK]))
start.error(p, SyntaxError::Expected(vec![EXPR, R_BRACK]))
}
}

View file

@ -16,7 +16,7 @@ pub fn pipeline(p: &mut Parser, start_expr: CompletedMarker) -> Option<Completed
loop {
if expression(p, true).is_none() {
return Some(pipeline_marker.complete_err(p, SyntaxError::PipelineNeedsSink));
return Some(pipeline_marker.error(p, SyntaxError::PipelineNeedsSink));
}
if !pipe(p) {
return Some(pipeline_marker.complete(p, PIPELINE));

View file

@ -1,3 +1,4 @@
use clap::builder;
use owo_colors::{unset_override, OwoColorize};
use rowan::{GreenNode, GreenNodeBuilder, GreenNodeData, GreenTokenData, Language, NodeOrToken};
use std::mem;
@ -7,7 +8,10 @@ use crate::lst_parser::{
syntax_kind::{Lang, SyntaxKind},
};
use super::{error::SyntaxError, events::Event};
use super::{
error::SyntaxError,
events::{Event, NodeKind},
};
pub struct Output {
pub green_node: GreenNode,
@ -23,6 +27,7 @@ impl std::fmt::Debug for Output {
}
}
const INDENT_STR: &str = " ";
fn debug_print_green_node(
node: NodeOrToken<&GreenNodeData, &GreenTokenData>,
f: &mut dyn std::fmt::Write,
@ -31,7 +36,7 @@ fn debug_print_green_node(
colored: bool,
) -> std::fmt::Result {
for _ in 0..lvl {
f.write_str(" ")?;
f.write_str(INDENT_STR)?;
}
if !colored {
@ -68,7 +73,7 @@ fn debug_print_green_node(
debug_print_green_node(c, f, lvl + 1, errs, colored)?;
}
for _ in 0..lvl {
f.write_str(" ")?;
f.write_str(INDENT_STR)?;
}
if kind != SyntaxKind::PARSE_ERR {
write!(f, "{}", "}\n".yellow())
@ -123,10 +128,11 @@ impl Output {
}
pub fn from_parser_output(
mut raw_toks: Vec<(SyntaxKind, &str)>,
(mut events, errs): (Vec<Event>, Vec<SyntaxError>),
mut events: Vec<Event>,
) -> Self {
let mut builder = GreenNodeBuilder::new();
let mut fw_parents = Vec::new();
let mut errors = Vec::new();
raw_toks.reverse();
for i in 0..events.len() {
@ -170,8 +176,15 @@ impl Output {
}
for kind in fw_parents.drain(..).rev() {
if kind != SyntaxKind::TOMBSTONE {
builder.start_node(kind.into());
match kind {
NodeKind::Syntax(kind) if kind != SyntaxKind::TOMBSTONE => {
builder.start_node(kind.into())
}
NodeKind::Error(err) => {
errors.push(err);
builder.start_node(SyntaxKind::PARSE_ERR.into())
}
_ => {}
}
}
}
@ -180,13 +193,12 @@ impl Output {
let (tok, text): (SyntaxKind, &str) = raw_toks.pop().unwrap();
builder.token(tok.into(), text);
}),
Event::Error => todo!(),
}
}
Self {
green_node: builder.finish(),
errors: errs,
errors,
}
}
}