oak-bat 0.0.11

High-performance incremental Windows Batch (BAT) parser for the oak ecosystem with flexible configuration, supporting shell scripting and automation workflows.
Documentation
#![doc = include_str!("readme.md")]
/// Token type definitions for Windows Batch (BAT) lexical analysis.
///
/// This module provides [`BatTokenType`] which defines all token types
/// recognized by the BAT lexer, including keywords, labels, and text.
pub mod token_type;

pub use token_type::BatTokenType;

use crate::language::BatLanguage;
use oak_core::{Lexer, LexerCache, LexerState, OakError, lexer::LexOutput, source::Source};

pub(crate) type State<'a, S> = LexerState<'a, S, BatLanguage>;

/// Lexer for Windows Batch (BAT) files.
///
/// This lexer tokenizes BAT source code into a sequence of tokens
/// that can be processed by the parser.
#[derive(Clone)]
pub struct BatLexer<'config> {
    config: &'config BatLanguage,
}

impl<'config> Lexer<BatLanguage> for BatLexer<'config> {
    fn lex<'a, S: Source + ?Sized>(&self, source: &S, _edits: &[oak_core::source::TextEdit], cache: &'a mut impl LexerCache<BatLanguage>) -> LexOutput<BatLanguage> {
        let mut state = LexerState::new_with_cache(source, 0, cache);
        let result = self.run(&mut state);
        if result.is_ok() {
            state.add_eof()
        }
        state.finish_with_cache(result, cache)
    }
}

impl<'config> BatLexer<'config> {
    /// Creates a new `BatLexer` instance with the specified language configuration.
    ///
    /// # Arguments
    ///
    /// * `config` - A reference to the `BatLanguage` configuration.
    pub fn new(config: &'config BatLanguage) -> Self {
        Self { config }
    }

    fn run<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
        while state.not_at_end() {
            let start_pos = state.get_position();
            if let Some(ch) = state.peek() {
                state.advance(ch.len_utf8());
                state.add_token(BatTokenType::Text, start_pos, state.get_position())
            }
        }
        Ok(())
    }
}