From 852543212ba5c68b3428a80187087cc641de612c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 4 Feb 2018 14:35:59 +0300 Subject: Extract parser input into a separate struct --- src/parser/input.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parser/mod.rs | 4 ++- src/parser/parser.rs | 36 ++++++------------------ 3 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 src/parser/input.rs diff --git a/src/parser/input.rs b/src/parser/input.rs new file mode 100644 index 000000000..162b9ef5f --- /dev/null +++ b/src/parser/input.rs @@ -0,0 +1,77 @@ +use {SyntaxKind, TextRange, TextUnit, Token}; +use syntax_kinds::EOF; +use super::is_insignificant; + +use std::ops::{Add, AddAssign}; + +pub(crate) struct ParserInput<'t> { + #[allow(unused)] + text: &'t str, + #[allow(unused)] + start_offsets: Vec, + tokens: Vec, // non-whitespace tokens +} + +impl<'t> ParserInput<'t> { + pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> { + let mut tokens = Vec::new(); + let mut start_offsets = Vec::new(); + let mut len = TextUnit::new(0); + for &token in raw_tokens.iter() { + if !is_insignificant(token.kind) { + tokens.push(token); + start_offsets.push(len); + } + len += token.len; + } + + ParserInput { + text, + start_offsets, + tokens, + } + } + + pub fn kind(&self, pos: InputPosition) -> SyntaxKind { + let idx = pos.0 as usize; + if !(idx < self.tokens.len()) { + return EOF; + } + self.tokens[idx].kind + } + + #[allow(unused)] + pub fn text(&self, pos: InputPosition) -> &'t str { + let idx = pos.0 as usize; + if !(idx < self.tokens.len()) { + return ""; + } + let start_offset = self.start_offsets[idx]; + let end_offset = self.tokens[idx].len; + let range = TextRange::from_to(start_offset, end_offset); + &self.text[range] + } +} + +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub(crate) struct InputPosition(u32); + +impl InputPosition { + pub fn new() -> Self { + InputPosition(0) + } +} + +impl Add for InputPosition { + type Output = InputPosition; + + fn add(self, rhs: u32) -> InputPosition { + InputPosition(self.0 + rhs) + } +} + +impl AddAssign for InputPosition { + fn add_assign(&mut self, rhs: u32) { + self.0 += rhs + } +} diff --git a/src/parser/mod.rs b/src/parser/mod.rs index f17ffbf3a..49a69900f 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -4,6 +4,7 @@ use syntax_kinds::*; #[macro_use] mod parser; +mod input; mod event; mod grammar; use self::event::Event; @@ -11,7 +12,8 @@ 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 mut parser = parser::Parser::new(&text, tokens); + let input = input::ParserInput::new(&text, tokens); + let mut parser = parser::Parser::new(&input); grammar::file(&mut parser); parser.into_events() }; diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 3f4c8a07d..bb775c4a5 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -1,7 +1,6 @@ -use {SyntaxKind, TextUnit, Token}; use super::Event; -use super::is_insignificant; -use SyntaxKind::{EOF, TOMBSTONE}; +use super::input::{InputPosition, ParserInput}; +use SyntaxKind::{self, EOF, TOMBSTONE}; pub(crate) struct Marker { pos: u32, @@ -98,35 +97,18 @@ macro_rules! token_set { } pub(crate) struct Parser<'t> { - #[allow(unused)] - text: &'t str, - #[allow(unused)] - start_offsets: Vec, - tokens: Vec, // non-whitespace tokens + inp: &'t ParserInput<'t>, - pos: usize, + pos: InputPosition, events: Vec, } impl<'t> Parser<'t> { - pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> { - let mut tokens = Vec::new(); - let mut start_offsets = Vec::new(); - let mut len = TextUnit::new(0); - for &token in raw_tokens.iter() { - if !is_insignificant(token.kind) { - tokens.push(token); - start_offsets.push(len); - } - len += token.len; - } - + pub(crate) fn new(inp: &'t ParserInput<'t>) -> Parser<'t> { Parser { - text, - start_offsets, - tokens, + inp, - pos: 0, + pos: InputPosition::new(), events: Vec::new(), } } @@ -163,8 +145,8 @@ impl<'t> Parser<'t> { }); } - pub(crate) fn nth(&self, n: usize) -> SyntaxKind { - self.tokens.get(self.pos + n).map(|t| t.kind).unwrap_or(EOF) + pub(crate) fn nth(&self, n: u32) -> SyntaxKind { + self.inp.kind(self.pos + n) } pub(crate) fn current(&self) -> SyntaxKind { -- cgit v1.2.3