Compare commits

...

3 commits

6 changed files with 113 additions and 6 deletions

View file

@ -1,6 +1,6 @@
use crate::syntax_kind::SyntaxKind; use crate::syntax_kind::SyntaxKind;
#[derive(Clone)] #[derive(Clone, PartialEq, Eq)]
pub enum SyntaxError { pub enum SyntaxError {
DisallowedKeyType(SyntaxKind), DisallowedKeyType(SyntaxKind),
MemberMissingValue, MemberMissingValue,

View file

@ -1,6 +1,9 @@
use std::cell::Cell; use std::{cell::Cell, marker::PhantomData, mem};
use enumset::{EnumSet, EnumSetType}; use enumset::{EnumSet, EnumSetType};
use rowan::{GreenNode, GreenNodeBuilder};
use crate::parser::event::NodeKind;
use self::{event::Event, input::Input, marker::Marker}; use self::{event::Event, input::Input, marker::Marker};
pub use error::SyntaxError; pub use error::SyntaxError;
@ -13,7 +16,7 @@ pub mod marker;
/// this is used to define some required SyntaxKinds like an EOF token or an error token /// this is used to define some required SyntaxKinds like an EOF token or an error token
pub trait SyntaxElement pub trait SyntaxElement
where where
Self: EnumSetType + Into<rowan::SyntaxKind> + Clone, Self: EnumSetType + Into<rowan::SyntaxKind> + Clone + PartialEq + 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 EOF: Self;
@ -93,6 +96,90 @@ impl<'src, 'toks, SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError>
assert!(steps <= self.step_limit, "the parser seems stuck."); assert!(steps <= self.step_limit, "the parser seems stuck.");
self.steps.set(steps + 1); self.steps.set(steps + 1);
} }
pub fn finish(
Self {
input,
pos,
mut events,
step_limit,
steps,
}: Self,
) -> ParserOutput<SyntaxKind, SyntaxErr> {
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<SyntaxErr> = 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< pub struct ParserBuilder<

View file

@ -2,6 +2,6 @@
// TODO: constrain that conversion to `NodeKind::Error` is enforced to be possible // TODO: constrain that conversion to `NodeKind::Error` is enforced to be possible
pub trait SyntaxError pub trait SyntaxError
where where
Self: Clone, Self: Clone + PartialEq + Eq,
{ {
} }

View file

@ -22,7 +22,7 @@ impl<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> Event<SyntaxKind, Syntax
} }
} }
#[derive(Clone)] #[derive(Clone, PartialEq, Eq)]
pub enum NodeKind<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> { pub enum NodeKind<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> {
Tombstone, Tombstone,
Syntax(SyntaxKind), Syntax(SyntaxKind),

View file

@ -55,4 +55,13 @@ impl<'src, SyntaxKind: SyntaxElement> Input<'src, SyntaxKind> {
pub fn meaningless_tail_len(&self) -> usize { pub fn meaningless_tail_len(&self) -> usize {
self.raw.len() - (self.meaningful_toks.last().unwrap() + 1) self.raw.len() - (self.meaningful_toks.last().unwrap() + 1)
} }
pub fn dissolve(self) -> (Vec<(SyntaxKind, &'src str)>, EnumSet<SyntaxKind>) {
let Self {
raw,
semantically_meaningless,
..
} = self;
(raw, semantically_meaningless)
}
} }

View file

@ -69,6 +69,17 @@ pub struct CompletedMarker<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> {
impl<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> CompletedMarker<SyntaxKind, SyntaxErr> { impl<SyntaxKind: SyntaxElement, SyntaxErr: SyntaxError> CompletedMarker<SyntaxKind, SyntaxErr> {
pub fn precede(self, p: &mut Parser<SyntaxKind, SyntaxErr>, name: &str) -> Marker { pub fn precede(self, p: &mut Parser<SyntaxKind, SyntaxErr>, name: &str) -> Marker {
todo!() let new_pos = p.start(name);
match &mut p.events[self.pos] {
Event::Start { forward_parent, .. } => {
// point forward parent of the node this marker completed to the new node
// will later be used to make the new node a parent of the current node.
*forward_parent = Some(new_pos.pos - self.pos)
}
_ => unreachable!(),
}
new_pos
} }
} }