pawarser, json-pawarser: get first debug print working!

This commit is contained in:
Schrottkatze 2024-10-21 18:29:46 +02:00
parent af6886214b
commit b8720b2df9
Signed by: schrottkatze
SSH key fingerprint: SHA256:hXb3t1vINBFCiDCmhRABHX5ocdbLiKyCdKI4HK2Rbbc
7 changed files with 140 additions and 23 deletions

View file

@ -1,4 +1,4 @@
use std::{cell::Cell, marker::PhantomData, mem};
use std::{cell::Cell, fmt, marker::PhantomData, mem};
use enumset::{EnumSet, EnumSetType};
use rowan::{GreenNode, GreenNodeBuilder};
@ -6,17 +6,24 @@ use rowan::{GreenNode, GreenNodeBuilder};
use crate::parser::event::NodeKind;
use self::{event::Event, input::Input, marker::Marker};
pub use error::SyntaxError;
pub use {error::SyntaxError, output::ParserOutput};
pub mod error;
mod event;
mod input;
pub mod marker;
pub mod output;
/// this is used to define some required SyntaxKinds like an EOF token or an error token
pub trait SyntaxElement
where
Self: EnumSetType + Into<rowan::SyntaxKind> + Clone + PartialEq + Eq,
Self: EnumSetType
+ Into<rowan::SyntaxKind>
+ From<rowan::SyntaxKind>
+ fmt::Debug
+ Clone
+ PartialEq
+ Eq,
{
/// EOF value. This will be used by the rest of the parser library to represent an EOF.
const EOF: Self;
@ -97,15 +104,14 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>
self.steps.set(steps + 1);
}
pub fn finish(
Self {
pub fn finish(self) -> ParserOutput<SyntaxKind, SyntaxErr> {
let Self {
input,
pos,
mut events,
step_limit,
steps,
}: Self,
) -> ParserOutput<SyntaxKind, SyntaxErr> {
} = self;
let (mut raw_toks, meaningless_tokens) = input.dissolve();
let mut builder = GreenNodeBuilder::new();
// TODO: document what the hell a forward parent is
@ -178,7 +184,11 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>
}
}
todo!()
ParserOutput {
green_node: builder.finish(),
errors,
_syntax_kind: PhantomData::<SyntaxKind>,
}
}
}

View file

@ -1,7 +1,9 @@
use std::fmt;
/// A marker trait... for now!
// TODO: constrain that conversion to `NodeKind::Error` is enforced to be possible
pub trait SyntaxError
where
Self: Clone + PartialEq + Eq,
Self: fmt::Debug + Clone + PartialEq + Eq,
{
}

View file

@ -0,0 +1,67 @@
use std::{fmt, marker::PhantomData};
use rowan::{GreenNode, GreenNodeData, GreenTokenData, NodeOrToken};
use crate::{SyntaxElement, SyntaxError};
pub struct ParserOutput<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> {
pub green_node: GreenNode,
pub errors: Vec<SyntaxErr>,
pub(super) _syntax_kind: PhantomData<SyntaxKind>,
}
impl<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> std::fmt::Debug
for ParserOutput<SyntaxKind, SyntaxErr>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut errs: Vec<&SyntaxErr> = self.errors.iter().collect();
errs.reverse();
debug_print_output::<SyntaxKind, SyntaxErr>(
NodeOrToken::Node(&self.green_node),
f,
0,
&mut errs,
)
}
}
fn debug_print_output<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>(
node: NodeOrToken<&GreenNodeData, &GreenTokenData>,
f: &mut std::fmt::Formatter<'_>,
lvl: i32,
errs: &mut Vec<&SyntaxErr>,
) -> std::fmt::Result {
for _ in 0..lvl {
f.write_str(" ")?;
}
match node {
NodeOrToken::Node(n) => {
let kind: SyntaxKind = node.kind().into();
if kind != SyntaxKind::ERROR {
writeln!(f, "{:?} {{", kind)?;
} else {
let err = errs
.pop()
.expect("all error syntax nodes should correspond to an error");
writeln!(f, "{:?}: {err:?} {{", kind)?;
}
for c in n.children() {
debug_print_output::<SyntaxKind, SyntaxErr>(c, f, lvl + 1, errs)?;
}
for _ in 0..lvl {
f.write_str(" ")?;
}
f.write_str("}\n")
}
NodeOrToken::Token(t) => {
writeln!(
f,
"{:?} {:?};",
Into::<SyntaxKind>::into(t.kind()),
t.text()
)
}
}
}