1pub mod strmatcher;
2pub mod general;
3pub mod literals;
4pub mod keywords;
5pub mod comments;
6
7pub use general::*;
8
9
10use std::error::Error;
11use crate::lexer::Token;
12
13trait WordChar {
17 fn is_word_alphanumeric(&self) -> bool;
18 fn is_word_alphabetic(&self) -> bool;
19 fn is_word_ascii_alphanumeric(&self) -> bool;
20 fn is_word_ascii_alphabetic(&self) -> bool;
21}
22
23impl WordChar for char {
24 fn is_word_alphanumeric(&self) -> bool {
25 *self == '_' || self.is_alphanumeric()
26 }
27
28 fn is_word_alphabetic(&self) -> bool {
29 *self == '_' || self.is_alphabetic()
30 }
31
32 fn is_word_ascii_alphanumeric(&self) -> bool {
33 *self == '_' || self.is_ascii_alphanumeric()
34 }
35
36 fn is_word_ascii_alphabetic(&self) -> bool {
37 *self == '_' || self.is_ascii_alphabetic()
38 }
39}
40
41#[derive(Clone, Copy)]
44pub enum MatchResult {
45 IncompleteMatch,
47
48 CompleteMatch,
51
52 NoMatch,
54}
55
56impl MatchResult {
57 pub fn is_match(&self) -> bool {
58 match self {
59 MatchResult::IncompleteMatch | MatchResult::CompleteMatch => true,
60 MatchResult::NoMatch => false,
61 }
62 }
63
64 pub fn is_complete_match(&self) -> bool { matches!(self, MatchResult::CompleteMatch) }
65
66 pub fn is_incomplete_match(&self) -> bool { matches!(self, MatchResult::IncompleteMatch) }
67}
68
69type TokenError = Box<dyn Error + 'static>;
71
72pub trait LexerRule: __LexerRule_Clone {
73 fn reset(&mut self);
74
75 fn current_state(&self) -> MatchResult;
76
77 fn try_match(&mut self, prev: Option<char>, next: char) -> MatchResult;
80
81 fn get_token(&self) -> Result<Token, TokenError>;
85}
86
87
88#[allow(non_camel_case_types)]
96pub trait __LexerRule_Clone {
97 fn __clone_box(&self) -> Box<dyn LexerRule>;
98}
99
100impl<T> __LexerRule_Clone for T where T: 'static + LexerRule + Clone {
101 fn __clone_box(&self) -> Box<dyn LexerRule> { Box::new(self.clone()) }
102}
103
104impl Clone for Box<dyn LexerRule> {
105 fn clone(&self) -> Box<dyn LexerRule> { self.__clone_box() }
106}