diff --git a/src/parser/event.rs b/src/parser/event.rs index 90348398ee0..30fe5c6d71f 100644 --- a/src/parser/event.rs +++ b/src/parser/event.rs @@ -61,7 +61,7 @@ pub(crate) enum Event { }, Error { - message: String, + msg: String, }, } @@ -140,8 +140,8 @@ pub(super) fn to_file(text: String, tokens: &[Token], events: Vec) -> Fil } builder.leaf(kind, len); } - &Event::Error { ref message } => builder.error(ErrorMsg { - message: message.clone(), + &Event::Error { ref msg } => builder.error(ErrorMsg { + msg: msg.clone(), }), } } diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index f5b63aaabcb..e29cf9b02b8 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs @@ -1,4 +1,5 @@ -use super::parser::{Parser, TokenSet}; +use parser::parser::{Parser}; +use parser::token_set::TokenSet; use SyntaxKind; use syntax_kinds::*; diff --git a/src/parser/mod.rs b/src/parser/mod.rs index c23ed33495c..3814837e11a 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3,19 +3,20 @@ use {File, SyntaxKind, Token}; use syntax_kinds::*; #[macro_use] +mod token_set; mod parser; mod input; mod event; mod grammar; -use self::event::Event; /// Parse a sequence of tokens into the representative node tree pub fn parse(text: String, tokens: &[Token]) -> File { let events = { let input = input::ParserInput::new(&text, tokens); - let mut parser = parser::Parser::new(&input); + let parser_impl = parser::imp::ParserImpl::new(&input); + let mut parser = parser::Parser(parser_impl); grammar::file(&mut parser); - parser.into_events() + parser.0.into_events() }; event::to_file(text, tokens, events) } @@ -26,33 +27,3 @@ fn is_insignificant(kind: SyntaxKind) -> bool { _ => false, } } - -impl<'p> parser::Parser<'p> { - fn at(&self, kind: SyntaxKind) -> bool { - self.current() == kind - } - - fn err_and_bump(&mut self, message: &str) { - let err = self.start(); - self.error(message); - self.bump(); - err.complete(self, ERROR); - } - - fn expect(&mut self, kind: SyntaxKind) -> bool { - if self.at(kind) { - self.bump(); - true - } else { - self.error(format!("expected {:?}", kind)); - false - } - } - - fn eat(&mut self, kind: SyntaxKind) -> bool { - self.at(kind) && { - self.bump(); - true - } - } -} diff --git a/src/parser/parser.rs b/src/parser/parser.rs deleted file mode 100644 index 7c8e47cb6f6..00000000000 --- a/src/parser/parser.rs +++ /dev/null @@ -1,193 +0,0 @@ -use super::Event; -use super::input::{InputPosition, ParserInput}; -use SyntaxKind::{self, 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 TokenSet { - pub tokens: &'static [SyntaxKind], -} - -impl TokenSet { - pub fn contains(&self, kind: SyntaxKind) -> bool { - self.tokens.contains(&kind) - } -} - -#[macro_export] -macro_rules! token_set { - ($($t:ident),*) => { - TokenSet { - tokens: &[$($t),*], - } - }; - - ($($t:ident),* ,) => { - token_set!($($t),*) - }; -} - -pub(crate) struct Parser<'t> { - inp: &'t ParserInput<'t>, - - pos: InputPosition, - events: Vec, -} - -impl<'t> Parser<'t> { - pub(crate) fn new(inp: &'t ParserInput<'t>) -> Parser<'t> { - Parser { - inp, - - pos: InputPosition::new(), - events: Vec::new(), - } - } - - pub(crate) fn into_events(self) -> Vec { - assert_eq!(self.current(), EOF); - self.events - } - - 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, T: Into>(&'p mut self, msg: T) -> ErrorBuilder<'p, 't> { - ErrorBuilder::new(self, msg.into()) - } - - pub(crate) fn bump(&mut self) { - let kind = self.current(); - if kind == EOF { - return; - } - self.pos += 1; - self.event(Event::Token { - kind, - n_raw_tokens: 1, - }); - } - - pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { - if self.current() == EOF { - // TODO: panic!? - return; - } - self.pos += 1; - self.event(Event::Token { - kind, - n_raw_tokens: 1, - }); - } - - pub(crate) fn nth(&self, n: u32) -> SyntaxKind { - self.inp.kind(self.pos + n) - } - - pub(crate) fn at_kw(&self, t: &str) -> bool { - self.inp.text(self.pos) == t - } - - pub(crate) fn current(&self) -> SyntaxKind { - self.nth(0) - } - - fn event(&mut self, event: Event) { - self.events.push(event) - } -} - -pub(crate) struct ErrorBuilder<'p, 't: 'p> { - message: String, - parser: &'p mut Parser<'t>, -} - -impl<'p, 't: 'p> Drop for ErrorBuilder<'p, 't> { - fn drop(&mut self) { - let message = ::std::mem::replace(&mut self.message, String::new()); - self.parser.event(Event::Error { message }); - } -} - -impl<'t, 'p> ErrorBuilder<'p, 't> { - fn new(parser: &'p mut Parser<'t>, message: String) -> Self { - ErrorBuilder { message, parser } - } -} diff --git a/src/parser/parser/imp.rs b/src/parser/parser/imp.rs new file mode 100644 index 00000000000..2b16e11b93f --- /dev/null +++ b/src/parser/parser/imp.rs @@ -0,0 +1,118 @@ +use parser::input::{ParserInput, InputPosition}; +use parser::event::Event; + +use SyntaxKind; +use syntax_kinds::{TOMBSTONE, EOF}; + +pub(crate) struct ParserImpl<'t> { + inp: &'t ParserInput<'t>, + + pos: InputPosition, + events: Vec, +} + +impl<'t> ParserImpl<'t> { + pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { + ParserImpl { + inp, + + pos: InputPosition::new(), + events: Vec::new(), + } + } + + pub(crate) fn into_events(self) -> Vec { + assert_eq!(self.nth(0), EOF); + self.events + } + + + pub(super) fn nth(&self, n: u32) -> SyntaxKind { + self.inp.kind(self.pos + n) + } + + pub(super) fn at_kw(&self, t: &str) -> bool { + self.inp.text(self.pos) == t + } + + pub(super) fn start(&mut self) -> u32 { + let pos = self.events.len() as u32; + self.event(Event::Start { + kind: TOMBSTONE, + forward_parent: None, + }); + pos + } + + pub(super) fn bump(&mut self) { + let kind = self.nth(0); + if kind == EOF { + return; + } + self.do_bump(kind); + } + + pub(super) fn bump_remap(&mut self, kind: SyntaxKind) { + if self.nth(0) == EOF { + // TODO: panic!? + return; + } + self.do_bump(kind); + } + + fn do_bump(&mut self, kind: SyntaxKind) { + self.pos += 1; + self.event(Event::Token { + kind, + n_raw_tokens: 1, + }); + } + + pub(super) fn error(&mut self, msg: String) { + self.event(Event::Error { msg }) + } + + pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { + match self.events[pos as usize] { + Event::Start { + kind: ref mut slot, .. + } => { + *slot = kind; + } + _ => unreachable!(), + } + self.event(Event::Finish); + } + + pub(super) fn abandon(&mut self, pos: u32) { + let idx = pos as usize; + if idx == self.events.len() - 1 { + match self.events.pop() { + Some(Event::Start { + kind: TOMBSTONE, + forward_parent: None, + }) => (), + _ => unreachable!(), + } + } + } + + pub(super) fn precede(&mut self, pos: u32) -> u32 { + let new_pos = self.start(); + match self.events[pos as usize] { + Event::Start { + ref mut forward_parent, + .. + } => { + *forward_parent = Some(new_pos - pos); + } + _ => unreachable!(), + } + new_pos + } + + + fn event(&mut self, event: Event) { + self.events.push(event) + } +} diff --git a/src/parser/parser/mod.rs b/src/parser/parser/mod.rs new file mode 100644 index 00000000000..c8db2091817 --- /dev/null +++ b/src/parser/parser/mod.rs @@ -0,0 +1,100 @@ +use SyntaxKind; +use syntax_kinds::ERROR; + +pub(super) mod imp; +use self::imp::ParserImpl; + +pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>); + + +impl<'t> Parser<'t> { + pub(crate) fn current(&self) -> SyntaxKind { + self.nth(0) + } + + pub(crate) fn nth(&self, n: u32) -> SyntaxKind { + self.0.nth(n) + } + + pub(crate) fn at(&self, kind: SyntaxKind) -> bool { + self.current() == kind + } + + pub(crate) fn at_kw(&self, t: &str) -> bool { + self.0.at_kw(t) + } + + pub(crate) fn start(&mut self) -> Marker { + Marker(self.0.start()) + } + + pub(crate) fn bump(&mut self) { + self.0.bump(); + } + + pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { + self.0.bump_remap(kind); + } + + pub(crate) fn error>(&mut self, message: T) { + self.0.error(message.into()) + } + + pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { + if self.at(kind) { + self.bump(); + return true; + } + self.error(format!("expected {:?}", kind)); + false + } + + pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool { + if !self.at(kind) { + return false; + } + self.bump(); + true + } + + pub(crate) fn err_and_bump(&mut self, message: &str) { + let m = self.start(); + self.error(message); + self.bump(); + m.complete(self, ERROR); + } +} + +pub(crate) struct Marker(u32); + +impl Marker { + pub(crate) fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { + let pos = self.0; + ::std::mem::forget(self); + p.0.complete(pos, kind); + CompletedMarker(pos) + } + + pub(crate) fn abandon(self, p: &mut Parser) { + let pos = self.0; + ::std::mem::forget(self); + p.0.abandon(pos); + } +} + +impl Drop for Marker { + fn drop(&mut self) { + if !::std::thread::panicking() { + panic!("Marker must be either completed or abandoned"); + } + } +} + + +pub(crate) struct CompletedMarker(u32); + +impl CompletedMarker { + pub(crate) fn precede(self, p: &mut Parser) -> Marker { + Marker(p.0.precede(self.0)) + } +} diff --git a/src/parser/token_set.rs b/src/parser/token_set.rs new file mode 100644 index 00000000000..82558fa2e75 --- /dev/null +++ b/src/parser/token_set.rs @@ -0,0 +1,25 @@ +use SyntaxKind; + +pub(crate) struct TokenSet { + pub tokens: &'static [SyntaxKind], +} + +impl TokenSet { + pub fn contains(&self, kind: SyntaxKind) -> bool { + self.tokens.contains(&kind) + } +} + +#[macro_export] +macro_rules! token_set { + ($($t:ident),*) => { + TokenSet { + tokens: &[$($t),*], + } + }; + + ($($t:ident),* ,) => { + token_set!($($t),*) + }; +} + diff --git a/src/tree/file_builder.rs b/src/tree/file_builder.rs index 3c7e2d7cfdb..f831676c739 100644 --- a/src/tree/file_builder.rs +++ b/src/tree/file_builder.rs @@ -70,7 +70,7 @@ impl Sink for FileBuilder { let &(node, after_child) = self.in_progress.last().unwrap(); self.errors.push(SyntaxErrorData { node, - message: err.message, + message: err.msg, after_child, }) } @@ -157,5 +157,5 @@ fn grow(left: &mut TextRange, right: TextRange) { #[derive(Default)] pub(crate) struct ErrorMsg { - pub(crate) message: String, + pub(crate) msg: String, }