From 0b5d39f2a204e5ec6cd6205440e4cdc763162814 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 20 Jan 2018 23:25:34 +0300 Subject: Markers API --- src/parser/event_parser/parser.rs | 112 ++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 36 deletions(-) (limited to 'src/parser/event_parser/parser.rs') diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs index 6171b3579..2bc9dd34f 100644 --- a/src/parser/event_parser/parser.rs +++ b/src/parser/event_parser/parser.rs @@ -1,8 +1,71 @@ use {Token, SyntaxKind, TextUnit}; -use super::{Event}; +use super::Event; use super::super::is_insignificant; use syntax_kinds::{L_CURLY, R_CURLY, ERROR}; -use tree::EOF; +use tree::{EOF, TOMBSTONE}; + +pub(crate) struct Marker { + pos: u32 +} + +impl Marker { + pub fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompleteMarker { + match self.event(p) { + &mut Event::Start { kind: ref mut slot, ..} => { + *slot = kind; + } + _ => unreachable!(), + } + p.event(Event::Finish); + let result = CompleteMarker { pos: self.pos }; + ::std::mem::forget(self); + result + } + + pub fn abandon(self, p: &mut Parser) { + let idx = self.pos as usize; + if idx == p.events.len() - 1 { + match p.events.pop() { + Some(Event::Start { kind: TOMBSTONE, forward_parent: None }) => (), + _ => unreachable!() + } + } + ::std::mem::forget(self); + } + + fn event<'p>(&self, p: &'p mut Parser) -> &'p mut Event { + &mut p.events[self.idx()] + } + + fn idx(&self) -> usize { + self.pos as usize + } +} + +impl Drop for Marker { + fn drop(&mut self) { + if !::std::thread::panicking() { + panic!("Each marker should be eithe completed or abandoned"); + } + } +} + +pub(crate) struct CompleteMarker { + pos: u32 +} + +impl CompleteMarker { + pub(crate) fn precede(self, p: &mut Parser) -> Marker { + let m = p.start(); + match p.events[self.pos as usize] { + Event::Start { ref mut forward_parent, ..} => { + *forward_parent = Some(m.pos - self.pos); + } + _ => unreachable!(), + } + m + } +} pub(crate) struct Parser<'t> { @@ -19,12 +82,9 @@ pub(crate) struct Parser<'t> { curly_limit: Option, } -#[derive(Debug, Clone, Copy,PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) struct Pos(u32); -#[derive(Debug, Clone, Copy,PartialEq, Eq)] -pub(crate) struct Mark(u32); - impl<'t> Parser<'t> { pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> { let mut tokens = Vec::new(); @@ -50,31 +110,13 @@ impl<'t> Parser<'t> { } } - pub(crate) fn mark(&self) -> Mark { - Mark(self.events.len() as u32) - } - - pub(crate) fn forward_parent(&mut self, child: Mark, parent: Mark) { - if child == parent || parent == self.mark() { - return - } - assert!(child.0 < parent.0); - let diff = parent.0 - child.0; - match self.events[child.0 as usize] { - Event::Start { ref mut forward_parent, .. } => { - *forward_parent = Some(diff); - } - _ => unreachable!() - } - } - pub(crate) fn pos(&self) -> Pos { Pos(self.pos as u32) } pub(crate) fn into_events(self) -> Vec { assert!(self.curly_limit.is_none()); - assert!(self.current() == EOF); + assert_eq!(self.current(), EOF); self.events } @@ -85,18 +127,16 @@ impl<'t> Parser<'t> { let token = self.tokens[self.pos]; if let Some(limit) = self.curly_limit { if limit == self.curly_level && token.kind == R_CURLY { - return EOF + return EOF; } } token.kind } - pub(crate) fn start(&mut self, kind: SyntaxKind) { - self.event(Event::Start { kind, forward_parent: None }); - } - - pub(crate) fn finish(&mut self) { - self.event(Event::Finish); + pub(crate) fn start(&mut self) -> Marker { + let m = Marker { pos: self.events.len() as u32 }; + self.event(Event::Start { kind: TOMBSTONE, forward_parent: None }); + m } pub(crate) fn error<'p>(&'p mut self) -> ErrorBuilder<'p, 't> { @@ -124,20 +164,20 @@ impl<'t> Parser<'t> { let old_level = self.curly_level; let old_limit = self.curly_limit; if !self.expect(L_CURLY) { - return false + return false; } self.curly_limit = Some(self.curly_level); f(self); assert!(self.curly_level > old_level); self.curly_limit = old_limit; if !self.expect(R_CURLY) { - self.start(ERROR); + let err = self.start(); while self.curly_level > old_level { if self.bump() == EOF { break; } } - self.finish(); + err.complete(self, ERROR); } true } @@ -149,7 +189,7 @@ impl<'t> Parser<'t> { pub(crate) struct ErrorBuilder<'p, 't: 'p> { message: Option, - parser: &'p mut Parser<'t> + parser: &'p mut Parser<'t>, } impl<'t, 'p> ErrorBuilder<'p, 't> { -- cgit v1.2.3