forked from katzen-cafe/iowo
lang: improve and simplify error handling and storage
fixes wrong error ordering with errors using `forward_parents`.
This commit is contained in:
parent
ed151c2e3c
commit
f6da90a354
8 changed files with 110 additions and 42 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue