tyml_parser 0.1.9

TYML: type checker for markup language
Documentation
use std::ops::Range;

use allocator_api2::vec::Vec;
use bumpalo::Bump;

use crate::lexer::{Lexer, Token, TokenKind};

#[derive(Debug)]
pub struct ParseError<'input, 'allocator> {
    pub kind: ParseErrorKind,
    pub scope: Scope,
    pub expected: Expected,
    pub error_tokens: &'allocator [Token<'input>],
    pub span: Range<usize>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Scope {
    Defines,
    ElementDefine,
    StructDefine,
    EnumDefine,
    TypeAttribute,
    Property,
    Interface,
    Function,
    Json,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Expected {
    Define,
    DefineSeparator,
    NodeLiteral,
    TypeOrValue,
    Type,
    Value,
    StructName,
    StructElementBlockOrTypeName,
    EnumName,
    EnumElementBlock,
    EnumElement,
    EnumElementSeparator,
    BraceLeft,
    BraceRight,
    BracketLeft,
    BracketRight,
    StringLiteral,
    FromTo,
    NumericLiteral,
    SmallerNumericLiteral,
    Unnecessary,
    TypeAttribute,
    ParenthesisLeft,
    ParenthesisRight,
    PropertyName,
    Equal,
    FunctionName,
    Return,
    LineFeed,
    InterfaceName,
    Colon,
    ErrorType,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseErrorKind {
    InvalidDefineElement,
    InvalidDefineSeparator,
    NotFoundElementTypeAndDefaultValue,
    InvalidElementTypeFormat,
    NonClosedBrace,
    UnknownDefaultValueFormat,
    NotFoundStructName,
    NotFoundStructBlock,
    NotFoundEnumName,
    NotFoundEnumBlock,
    InvalidEnumElement,
    InvalidEnumElementSeparator,
    InvalidOrTypeFormat,
    NotFoundArrayBaseType,
    NonClosedBracket,
    InvalidRegexAttributeFormat,
    NonFromTo,
    InvalidFromToFormat,
    NonNumeric,
    BiggerFrom,
    InvalidAndOrAttributeFormat,
    NonTypeAttribute,
    NonClosedParenthesis,
    InvalidPropertyFormat,
    InvalidInterfaceFormat,
    InvalidFunctionFormat,
    NonLineFeed,
    InvalidJsonArrayFormat,
    InvalidJsonObjectFormat,
    InvalidThrowsFormat,
}

pub(crate) fn recover_until<'input, 'allocator>(
    kind: ParseErrorKind,
    lexer: &mut Lexer<'input>,
    until: &[TokenKind],
    expected: Expected,
    scope: Scope,
    allocator: &'allocator Bump,
) -> ParseError<'input, 'allocator> {
    let anchor = lexer.cast_anchor();
    let mut error_tokens = Vec::new_in(allocator);

    loop {
        let token = match lexer.current() {
            Some(token) => token,
            None => break,
        };

        if until.contains(&token.kind) {
            break;
        }

        error_tokens.push(token);

        lexer.next();
    }

    let error_tokens = allocator.alloc(error_tokens);

    ParseError {
        kind,
        scope,
        expected,
        error_tokens,
        span: anchor.elapsed(lexer),
    }
}