skullbrain-parser 0.1.0

Parses skullbrain tokens into a concrete syntax tree (CST).
Documentation
use skullbrain_diagnostics::{EmitDiagnostics, ParseError};
use skullbrain_lexer::TokenKind;

use crate::{state::ConcreteSyntaxTreeBuilder, Diagnostics, ParserState, SyntaxKind};

impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
    /// Skip trivial tokens like whitespace or comments
    /// # Returns
    ///
    /// `true` if any token has been skipped
    pub(crate) fn skip_trivia(&mut self) -> bool {
        let mut has_skipped = false;

        while let Some(item) = self.peek() {
            match item.kind() {
                TokenKind::Whitespace => self.parse_token(SyntaxKind::Trivia),
                TokenKind::SingleLineComment => self.parse_token(SyntaxKind::Comment),
                TokenKind::MultiLineComment { is_terminated } => {
                    let is_terminated = *is_terminated;
                    self.parse_multiline_comment(is_terminated)
                }
                _ => break,
            };

            has_skipped = true;
        }

        has_skipped
    }

    fn parse_multiline_comment(&mut self, is_terminated: bool) {
        if !is_terminated {
            let details = self.diagnostic_details();
            self.emit_diagnostic(ParseError::unterminated_comment(), details);
        }

        self.parse_token(SyntaxKind::Comment)
    }
}

pub(crate) fn is_trivia(kind: &TokenKind) -> bool {
    kind.is_whitespace() || kind.is_multi_line_comment() || kind.is_single_line_comment()
}