#[macro_use] mod token_set; mod builder; mod lexer; mod parser_impl; mod parser_api; mod grammar; mod reparsing; use crate::{ SyntaxError, SyntaxKind, SmolStr, parsing::builder::GreenBuilder, syntax_node::GreenNode, }; pub use self::lexer::{tokenize, Token}; pub(crate) use self::reparsing::incremental_reparse; pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec) { let tokens = tokenize(&text); let (green, errors) = parser_impl::parse_with(GreenBuilder::new(), text, &tokens, grammar::root); (green, errors) } /// `TreeSink` abstracts details of a particular syntax tree implementation. trait TreeSink { type Tree; /// Adds new leaf to the current branch. fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); /// Start new branch and make it current. fn start_branch(&mut self, kind: SyntaxKind); /// Finish current branch and restore previous /// branch as current. fn finish_branch(&mut self); fn error(&mut self, error: SyntaxError); /// Complete tree building. Make sure that /// `start_branch` and `finish_branch` calls /// are paired! fn finish(self) -> Self::Tree; } /// `TokenSource` abstracts the source of the tokens parser operates one. /// /// Hopefully this will allow us to treat text and token trees in the same way! trait TokenSource { fn token_kind(&self, pos: TokenPos) -> SyntaxKind; fn is_token_joint_to_next(&self, pos: TokenPos) -> bool; fn is_keyword(&self, pos: TokenPos, kw: &str) -> bool; } #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Default)] pub(crate) struct TokenPos(pub u32); impl std::ops::Add for TokenPos { type Output = TokenPos; fn add(self, rhs: u32) -> TokenPos { TokenPos(self.0 + rhs) } } impl std::ops::AddAssign for TokenPos { fn add_assign(&mut self, rhs: u32) { self.0 += rhs } }