From ac75978c01b22264889d06f7e54633055dc2ff36 Mon Sep 17 00:00:00 2001 From: Schrottkatze Date: Mon, 21 Oct 2024 15:16:36 +0200 Subject: [PATCH] pawarser: Implement `Parser::finish` --- crates/pawarser/src/parser.rs | 89 ++++++++++++++++++++++++++++- crates/pawarser/src/parser/input.rs | 9 +++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/crates/pawarser/src/parser.rs b/crates/pawarser/src/parser.rs index bc4724f..ccbb5b2 100644 --- a/crates/pawarser/src/parser.rs +++ b/crates/pawarser/src/parser.rs @@ -1,6 +1,9 @@ -use std::cell::Cell; +use std::{cell::Cell, marker::PhantomData, mem}; use enumset::{EnumSet, EnumSetType}; +use rowan::{GreenNode, GreenNodeBuilder}; + +use crate::parser::event::NodeKind; use self::{event::Event, input::Input, marker::Marker}; pub use error::SyntaxError; @@ -93,6 +96,90 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> assert!(steps <= self.step_limit, "the parser seems stuck."); self.steps.set(steps + 1); } + + pub fn finish( + Self { + input, + pos, + mut events, + step_limit, + steps, + }: Self, + ) -> ParserOutput { + let (mut raw_toks, meaningless_tokens) = input.dissolve(); + let mut builder = GreenNodeBuilder::new(); + // TODO: document what the hell a forward parent is + let mut fw_parents = Vec::new(); + let mut errors: Vec = Vec::new(); + raw_toks.reverse(); + + for i in 0..events.len() { + match mem::replace(&mut events[i], Event::tombstone()) { + Event::Start { + kind, + forward_parent, + } => { + if kind == NodeKind::Tombstone && forward_parent.is_none() { + continue; + } + + // resolving forward parents + // temporarily jump around with the parser index and replace them with tombstones + fw_parents.push(kind); + let mut idx = i; + let mut fp = forward_parent; + while let Some(fwd) = fp { + idx += fwd as usize; + fp = match mem::replace(&mut events[idx], Event::tombstone()) { + Event::Start { + kind, + forward_parent, + } => { + fw_parents.push(kind); + forward_parent + } + _ => unreachable!(), + } + } + + // clear semantically meaningless tokens before the new tree node for aesthetic reasons + while raw_toks + .last() + .is_some_and(|v| meaningless_tokens.contains(v.0)) + { + // update first next Eat event + match events.iter_mut().find(|ev| matches!(ev, Event::Eat { .. })) { + Some(Event::Eat { count }) => *count -= 1, + _ => unreachable!(), + } + + // put whitespace into lst + let (tok, text) = raw_toks.pop().unwrap(); + builder.token(tok.into(), text); + } + + // insert forward parents into the tree in correct order + for kind in fw_parents.drain(..).rev() { + match kind { + NodeKind::Syntax(kind) => builder.start_node(kind.into()), + NodeKind::Error(err) => { + errors.push(err); + builder.start_node(SyntaxKind::ERROR.into()) + } + _ => {} + } + } + } + Event::Finish => builder.finish_node(), + Event::Eat { count } => (0..count).for_each(|_| { + let (tok, text) = raw_toks.pop().unwrap(); + builder.token(tok.into(), text); + }), + } + } + + todo!() + } } pub struct ParserBuilder< diff --git a/crates/pawarser/src/parser/input.rs b/crates/pawarser/src/parser/input.rs index 0a5ff60..a20d73d 100644 --- a/crates/pawarser/src/parser/input.rs +++ b/crates/pawarser/src/parser/input.rs @@ -55,4 +55,13 @@ impl<'src, SyntaxKind: SyntaxElement> Input<'src, SyntaxKind> { pub fn meaningless_tail_len(&self) -> usize { self.raw.len() - (self.meaningful_toks.last().unwrap() + 1) } + + pub fn dissolve(self) -> (Vec<(SyntaxKind, &'src str)>, EnumSet) { + let Self { + raw, + semantically_meaningless, + .. + } = self; + (raw, semantically_meaningless) + } }