Compare commits

..

3 commits

Author SHA1 Message Date
Schrottkatze 958857cb58
handle debug pretty printing 2024-10-27 17:21:42 +01:00
Schrottkatze 883b0c804e
add implicit root node to avoid crash on multiple root nodes 2024-10-27 16:59:18 +01:00
Schrottkatze f7d05ead2c
rename trait meta syntaxkinds 2024-10-27 16:56:39 +01:00
4 changed files with 31 additions and 16 deletions

View file

@ -62,13 +62,15 @@ pub enum SyntaxKind {
PARSE_ERR, PARSE_ERR,
// Meta SyntaxKinds // Meta SyntaxKinds
ROOT,
EOF, EOF,
} }
impl pawarser::parser::SyntaxElement for SyntaxKind { impl pawarser::parser::SyntaxElement for SyntaxKind {
const EOF: Self = Self::EOF; const SYNTAX_EOF: Self = Self::EOF;
const ERROR: Self = Self::PARSE_ERR; const SYNTAX_ERROR: Self = Self::PARSE_ERR;
const SYNTAX_ROOT: Self = Self::ROOT;
} }
impl From<SyntaxKind> for rowan::SyntaxKind { impl From<SyntaxKind> for rowan::SyntaxKind {

View file

@ -26,9 +26,10 @@ where
+ Eq, + Eq,
{ {
/// EOF value. This will be used by the rest of the parser library to represent an EOF. /// EOF value. This will be used by the rest of the parser library to represent an EOF.
const EOF: Self; const SYNTAX_EOF: Self;
/// Error value. This will be used as a placeholder for associated respective errors. /// Error value. This will be used as a placeholder for associated respective errors.
const ERROR: Self; const SYNTAX_ERROR: Self;
const SYNTAX_ROOT: Self;
} }
pub struct Parser<'src, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> { pub struct Parser<'src, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> {
@ -119,6 +120,9 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>
let mut errors: Vec<SyntaxErr> = Vec::new(); let mut errors: Vec<SyntaxErr> = Vec::new();
raw_toks.reverse(); raw_toks.reverse();
// always have an implicit root node to avoid [`GreenNodeBuilder::finish()`] panicking due to multiple root elements.
builder.start_node(SyntaxKind::SYNTAX_ROOT.into());
for i in 0..events.len() { for i in 0..events.len() {
match mem::replace(&mut events[i], Event::tombstone()) { match mem::replace(&mut events[i], Event::tombstone()) {
Event::Start { Event::Start {
@ -170,7 +174,7 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>
NodeKind::Syntax(kind) => builder.start_node(kind.into()), NodeKind::Syntax(kind) => builder.start_node(kind.into()),
NodeKind::Error(err) => { NodeKind::Error(err) => {
errors.push(err); errors.push(err);
builder.start_node(SyntaxKind::ERROR.into()) builder.start_node(SyntaxKind::SYNTAX_ERROR.into())
} }
_ => {} _ => {}
} }
@ -184,6 +188,9 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>
} }
} }
// finish SYNTAX_ROOT
builder.finish_node();
ParserOutput { ParserOutput {
green_node: builder.finish(), green_node: builder.finish(),
errors, errors,

View file

@ -34,7 +34,7 @@ impl<'src, SyntaxKind: SyntaxElement> Input<'src, SyntaxKind> {
pub fn kind(&self, idx: usize) -> SyntaxKind { pub fn kind(&self, idx: usize) -> SyntaxKind {
let Some(meaningful_idx) = self.meaningful_toks.get(idx) else { let Some(meaningful_idx) = self.meaningful_toks.get(idx) else {
return SyntaxKind::EOF; return SyntaxKind::SYNTAX_EOF;
}; };
self.raw.get(*meaningful_idx).unwrap().0 self.raw.get(*meaningful_idx).unwrap().0

View file

@ -31,34 +31,40 @@ fn debug_print_output<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>(
lvl: i32, lvl: i32,
errs: &mut Vec<&SyntaxErr>, errs: &mut Vec<&SyntaxErr>,
) -> std::fmt::Result { ) -> std::fmt::Result {
if f.alternate() {
for _ in 0..lvl { for _ in 0..lvl {
f.write_str(" ")?; f.write_str(" ")?;
} }
}
let maybe_newline = if f.alternate() { "\n" } else { " " };
match node { match node {
NodeOrToken::Node(n) => { NodeOrToken::Node(n) => {
let kind: SyntaxKind = node.kind().into(); let kind: SyntaxKind = node.kind().into();
if kind != SyntaxKind::ERROR { if kind != SyntaxKind::SYNTAX_ERROR {
writeln!(f, "{:?} {{", kind)?; write!(f, "{:?} {{{maybe_newline}", kind)?;
} else { } else {
let err = errs let err = errs
.pop() .pop()
.expect("all error syntax nodes should correspond to an error"); .expect("all error syntax nodes should correspond to an error");
writeln!(f, "{:?}: {err:?} {{", kind)?; write!(f, "{:?}: {err:?} {{{maybe_newline}", kind)?;
} }
for c in n.children() { for c in n.children() {
debug_print_output::<SyntaxKind, SyntaxErr>(c, f, lvl + 1, errs)?; debug_print_output::<SyntaxKind, SyntaxErr>(c, f, lvl + 1, errs)?;
} }
if f.alternate() {
for _ in 0..lvl { for _ in 0..lvl {
f.write_str(" ")?; f.write_str(" ")?;
} }
f.write_str("}\n") }
write!(f, "}}{maybe_newline}")
} }
NodeOrToken::Token(t) => { NodeOrToken::Token(t) => {
writeln!( write!(
f, f,
"{:?} {:?};", "{:?} {:?};{maybe_newline}",
Into::<SyntaxKind>::into(t.kind()), Into::<SyntaxKind>::into(t.kind()),
t.text() t.text()
) )