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