1pub mod lexer;
9pub mod lexer_dfa;
10pub mod parser;
11pub mod serialized;
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15pub enum AtnType {
16 Lexer,
17 Parser,
18}
19
20#[derive(Clone, Debug, Eq, PartialEq)]
27pub struct Atn {
28 grammar_type: AtnType,
29 max_token_type: i32,
30 states: Vec<AtnState>,
31 rule_to_start_state: Vec<usize>,
32 rule_to_stop_state: Vec<usize>,
33 rule_to_token_type: Vec<i32>,
34 mode_to_start_state: Vec<usize>,
35 decision_to_state: Vec<usize>,
36 lexer_actions: Vec<LexerAction>,
37}
38
39impl Atn {
40 pub const fn new(grammar_type: AtnType, max_token_type: i32) -> Self {
43 Self {
44 grammar_type,
45 max_token_type,
46 states: Vec::new(),
47 rule_to_start_state: Vec::new(),
48 rule_to_stop_state: Vec::new(),
49 rule_to_token_type: Vec::new(),
50 mode_to_start_state: Vec::new(),
51 decision_to_state: Vec::new(),
52 lexer_actions: Vec::new(),
53 }
54 }
55
56 pub const fn grammar_type(&self) -> AtnType {
57 self.grammar_type
58 }
59
60 pub const fn max_token_type(&self) -> i32 {
61 self.max_token_type
62 }
63
64 pub fn states(&self) -> &[AtnState] {
65 &self.states
66 }
67
68 pub fn state(&self, state_number: usize) -> Option<&AtnState> {
69 self.states.get(state_number)
70 }
71
72 pub fn state_mut(&mut self, state_number: usize) -> Option<&mut AtnState> {
73 self.states.get_mut(state_number)
74 }
75
76 pub fn add_state(&mut self, state: AtnState) -> usize {
79 let index = self.states.len();
80 self.states.push(state);
81 index
82 }
83
84 pub fn decision_to_state(&self) -> &[usize] {
85 &self.decision_to_state
86 }
87
88 pub fn add_decision_state(&mut self, state_number: usize) {
89 self.decision_to_state.push(state_number);
90 }
91
92 pub fn rule_to_start_state(&self) -> &[usize] {
93 &self.rule_to_start_state
94 }
95
96 pub fn set_rule_to_start_state(&mut self, rule_to_start_state: Vec<usize>) {
97 self.rule_to_start_state = rule_to_start_state;
98 }
99
100 pub fn rule_to_stop_state(&self) -> &[usize] {
101 &self.rule_to_stop_state
102 }
103
104 pub fn set_rule_to_stop_state(&mut self, rule_to_stop_state: Vec<usize>) {
105 self.rule_to_stop_state = rule_to_stop_state;
106 }
107
108 pub fn rule_to_token_type(&self) -> &[i32] {
109 &self.rule_to_token_type
110 }
111
112 pub fn set_rule_to_token_type(&mut self, rule_to_token_type: Vec<i32>) {
113 self.rule_to_token_type = rule_to_token_type;
114 }
115
116 pub fn mode_to_start_state(&self) -> &[usize] {
117 &self.mode_to_start_state
118 }
119
120 pub fn add_mode_start_state(&mut self, state_number: usize) {
121 self.mode_to_start_state.push(state_number);
122 }
123
124 pub fn lexer_actions(&self) -> &[LexerAction] {
125 &self.lexer_actions
126 }
127
128 pub fn set_lexer_actions(&mut self, lexer_actions: Vec<LexerAction>) {
129 self.lexer_actions = lexer_actions;
130 }
131}
132
133#[derive(Clone, Debug, Eq, PartialEq)]
140pub struct AtnState {
141 pub state_number: usize,
142 pub rule_index: Option<usize>,
143 pub kind: AtnStateKind,
144 pub end_state: Option<usize>,
145 pub loop_back_state: Option<usize>,
146 pub non_greedy: bool,
147 pub precedence_rule_decision: bool,
148 pub left_recursive_rule: bool,
149 pub transitions: Vec<Transition>,
150}
151
152impl AtnState {
153 pub const fn new(state_number: usize, kind: AtnStateKind) -> Self {
155 Self {
156 state_number,
157 rule_index: None,
158 kind,
159 end_state: None,
160 loop_back_state: None,
161 non_greedy: false,
162 precedence_rule_decision: false,
163 left_recursive_rule: false,
164 transitions: Vec::new(),
165 }
166 }
167
168 #[must_use]
169 pub const fn with_rule_index(mut self, rule_index: usize) -> Self {
170 self.rule_index = Some(rule_index);
171 self
172 }
173
174 pub fn add_transition(&mut self, transition: Transition) {
179 self.transitions.push(transition);
180 }
181
182 pub fn is_rule_stop(&self) -> bool {
183 self.kind == AtnStateKind::RuleStop
184 }
185}
186
187#[derive(Clone, Copy, Debug, Eq, PartialEq)]
189pub enum AtnStateKind {
190 Invalid,
191 Basic,
192 RuleStart,
193 BlockStart,
194 PlusBlockStart,
195 StarBlockStart,
196 TokenStart,
197 RuleStop,
198 BlockEnd,
199 StarLoopBack,
200 StarLoopEntry,
201 PlusLoopBack,
202 LoopEnd,
203}
204
205#[derive(Clone, Debug, Eq, PartialEq)]
211pub enum Transition {
212 Epsilon {
213 target: usize,
214 },
215 Atom {
216 target: usize,
217 label: i32,
218 },
219 Range {
220 target: usize,
221 start: i32,
222 stop: i32,
223 },
224 Set {
225 target: usize,
226 set: IntervalSet,
227 },
228 NotSet {
229 target: usize,
230 set: IntervalSet,
231 },
232 Wildcard {
233 target: usize,
234 },
235 Rule {
236 target: usize,
237 rule_index: usize,
238 follow_state: usize,
239 precedence: i32,
240 },
241 Predicate {
242 target: usize,
243 rule_index: usize,
244 pred_index: usize,
245 context_dependent: bool,
246 },
247 Action {
248 target: usize,
249 rule_index: usize,
250 action_index: Option<usize>,
251 context_dependent: bool,
252 },
253 Precedence {
254 target: usize,
255 precedence: i32,
256 },
257}
258
259impl Transition {
260 pub const fn target(&self) -> usize {
262 match self {
263 Self::Epsilon { target }
264 | Self::Atom { target, .. }
265 | Self::Range { target, .. }
266 | Self::Set { target, .. }
267 | Self::NotSet { target, .. }
268 | Self::Wildcard { target }
269 | Self::Rule { target, .. }
270 | Self::Predicate { target, .. }
271 | Self::Action { target, .. }
272 | Self::Precedence { target, .. } => *target,
273 }
274 }
275
276 pub const fn is_epsilon(&self) -> bool {
278 matches!(
279 self,
280 Self::Epsilon { .. }
281 | Self::Rule { .. }
282 | Self::Predicate { .. }
283 | Self::Action { .. }
284 | Self::Precedence { .. }
285 )
286 }
287
288 pub fn matches(&self, symbol: i32, min_vocabulary: i32, max_vocabulary: i32) -> bool {
293 match self {
294 Self::Atom { label, .. } => *label == symbol,
295 Self::Range { start, stop, .. } => (*start..=*stop).contains(&symbol),
296 Self::Set { set, .. } => set.contains(symbol),
297 Self::NotSet { set, .. } => {
298 (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol)
299 }
300 Self::Wildcard { .. } => (min_vocabulary..=max_vocabulary).contains(&symbol),
301 Self::Epsilon { .. }
302 | Self::Rule { .. }
303 | Self::Predicate { .. }
304 | Self::Action { .. }
305 | Self::Precedence { .. } => false,
306 }
307 }
308}
309
310#[derive(Clone, Debug, Default, Eq, PartialEq)]
315pub struct IntervalSet {
316 ranges: Vec<(i32, i32)>,
317}
318
319impl IntervalSet {
320 pub fn new() -> Self {
321 Self::default()
322 }
323
324 pub fn from_range(start: i32, stop: i32) -> Self {
325 let mut set = Self::new();
326 set.add_range(start, stop);
327 set
328 }
329
330 pub fn add(&mut self, value: i32) {
331 self.add_range(value, value);
332 }
333
334 pub fn add_range(&mut self, start: i32, stop: i32) {
337 let (start, stop) = if start <= stop {
338 (start, stop)
339 } else {
340 (stop, start)
341 };
342 self.ranges.push((start, stop));
343 self.normalize();
344 }
345
346 fn normalize(&mut self) {
348 self.ranges.sort_unstable();
349 let mut merged: Vec<(i32, i32)> = Vec::with_capacity(self.ranges.len());
350 for (start, stop) in self.ranges.drain(..) {
351 if let Some((_, last_stop)) = merged.last_mut() {
352 if start <= last_stop.saturating_add(1) {
353 *last_stop = (*last_stop).max(stop);
354 continue;
355 }
356 }
357 merged.push((start, stop));
358 }
359 self.ranges = merged;
360 }
361
362 pub fn contains(&self, value: i32) -> bool {
364 match self.ranges.binary_search_by(|(start, _)| start.cmp(&value)) {
371 Ok(_) => true,
372 Err(pos) => pos > 0 && self.ranges[pos - 1].1 >= value,
373 }
374 }
375
376 pub fn ranges(&self) -> &[(i32, i32)] {
377 &self.ranges
378 }
379
380 pub const fn is_empty(&self) -> bool {
381 self.ranges.is_empty()
382 }
383}
384
385#[derive(Clone, Debug, Eq, PartialEq)]
392pub enum LexerAction {
393 Channel(i32),
394 Custom { rule_index: i32, action_index: i32 },
395 Mode(i32),
396 More,
397 PopMode,
398 PushMode(i32),
399 Skip,
400 Type(i32),
401}
402
403#[cfg(test)]
404mod tests {
405 use super::*;
406
407 #[test]
408 fn interval_set_handles_ranges() {
409 let set = IntervalSet::from_range(2, 4);
410 assert!(set.contains(2));
411 assert!(set.contains(3));
412 assert!(set.contains(4));
413 assert!(!set.contains(5));
414 assert_eq!(set.ranges(), &[(2, 4)]);
415 }
416}