sphinx/lexer/rules/
comments.rs1use crate::lexer::Token;
2use crate::lexer::rules::{MatchResult, LexerRule, TokenError};
3use crate::lexer::rules::strmatcher::StrMatcher;
4
5#[derive(Clone)]
8pub struct LineCommentRule {
9 state: (bool, bool),
13 comment: char
14}
15
16impl LineCommentRule {
17 pub fn new(comment: char) -> Self {
18 LineCommentRule { comment, state: (false, false) }
19 }
20
21 fn match_state(&self, state: (bool, bool)) -> MatchResult {
22 match state {
23 (_, false) => MatchResult::CompleteMatch,
24 (true, _) => MatchResult::CompleteMatch,
25 (false, true) => MatchResult::NoMatch,
26 }
27 }
28
29 fn next_state(&self, state: (bool, bool), next: char) -> (bool, bool) {
30 let (start, end) = state;
31
32 if !start {
34 if next != self.comment {
35 return (false, true);
36 }
37 return (true, false);
38 }
39
40 if start && !end {
42 if next == '\n' {
43 return (true, true);
44 }
45 return (true, false);
46 }
47
48 (false, true)
50 }
51}
52
53impl LexerRule for LineCommentRule {
54 fn reset(&mut self) {
55 self.state = (false, false);
56 }
57
58 fn current_state(&self) -> MatchResult {
59 self.match_state(self.state)
60 }
61
62 fn try_match(&mut self, _prev: Option<char>, next: char) -> MatchResult {
63 let state = self.next_state(self.state, next);
64 let match_result = self.match_state(state);
65
66 if match_result.is_match() {
67 self.state = state;
68 }
69
70 match_result
71 }
72
73 fn get_token(&self) -> Result<Token, TokenError> {
75 debug_assert!(self.current_state().is_complete_match());
76 Ok(Token::Comment)
77 }
78}
79
80#[derive(Clone)]
81pub struct BlockCommentRule {
82 nestlevel: u32,
83 start: StrMatcher<'static>,
84 end: StrMatcher<'static>,
85}
86
87impl BlockCommentRule {
88 pub fn new(start: &'static str, end: &'static str) -> Self {
89 BlockCommentRule {
90 nestlevel: 0,
91 start: StrMatcher::case_sensitive(start),
92 end: StrMatcher::case_sensitive(end),
93 }
94 }
95}
96
97impl LexerRule for BlockCommentRule {
98 fn reset(&mut self) {
99 self.nestlevel = 0;
100 self.start.reset();
101 self.end.reset();
102 }
103
104 fn current_state(&self) -> MatchResult {
105 if self.nestlevel > 0 {
106 return MatchResult::IncompleteMatch;
107 }
108
109 if self.end.last_match_result().is_complete_match() {
110 return MatchResult::CompleteMatch;
111 }
112
113 self.start.last_match_result()
114 }
115
116 fn try_match(&mut self, _prev: Option<char>, next: char) -> MatchResult {
117
118 let start_result = self.start.try_match(next);
119 if start_result.is_complete_match() {
120 self.nestlevel += 1;
121 self.start.reset();
122 return MatchResult::IncompleteMatch;
123 }
124
125 if self.nestlevel > 0 {
126 let end_result = self.end.try_match(next);
127 if end_result.is_complete_match() {
128 self.nestlevel -= 1;
129
130 if self.nestlevel > 0 {
131 self.end.reset();
132 } else {
133 return MatchResult::CompleteMatch;
134 }
135 }
136
137 if !start_result.is_match() {
138 self.start.reset();
139 }
140 if !end_result.is_match() {
141 self.end.reset();
142 }
143
144 return MatchResult::IncompleteMatch;
145 }
146
147 start_result
148 }
149
150 fn get_token(&self) -> Result<Token, TokenError> {
152 debug_assert!(self.current_state().is_complete_match());
153 Ok(Token::Comment)
154 }
155}