Skip to main content

dbt_antlr4/
parser.rs

1//! Base parser implementation
2use std::borrow::{Borrow, Cow};
3use std::cell::Cell;
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut};
6
7use crate::arena::Arena;
8use crate::atn::ATN;
9use crate::atn_simulator::{IATNSimulator, ParserATNSimulatorManager};
10use crate::error_listener::{
11    ConsoleErrorListener, ErrorListener, ErrorListenerDelegate, ProxyErrorListener,
12};
13use crate::error_strategy::ErrorStrategy;
14use crate::errors::ANTLRError;
15use crate::interval_set::IntervalSet;
16use crate::parser_atn_simulator::ParserATNSimulator;
17use crate::recognizer::{Actions, Recognizer};
18use crate::rule_context::{states_stack, RuleContext as _};
19use crate::token::{Token, TOKEN_EOF};
20use crate::token_factory::TokenFactory;
21use crate::token_stream::TokenStream;
22use crate::tree::{NodeKindType, ParseTreeListener, Tree as _, TreeNode};
23use crate::utils::cell_update;
24use crate::vocabulary::Vocabulary;
25
26#[cfg(feature = "recursion-limit")]
27const DEFAULT_RECURSION_LIMIT: u32 = 2000;
28
29/// parser functionality required for `ParserATNSimulator` to work
30#[allow(missing_docs)]
31pub trait Parser<'input, 'arena, TF>: Recognizer<'input, 'arena, TF::Tok>
32where
33    'input: 'arena,
34    TF: TokenFactory<'input, 'arena> + 'arena,
35{
36    fn get_arena(&self) -> &'arena Arena;
37
38    fn get_interpreter(&self) -> &'arena ParserATNSimulator<'arena>;
39
40    fn get_token_factory(&self) -> &TF;
41
42    fn get_current_context(&self) -> &'arena TreeNode<'input, 'arena, Self::Node, TF::Tok>;
43
44    fn consume(
45        &mut self,
46        err_handler: &mut impl ErrorStrategy<'input, 'arena, TF, Self>,
47    ) -> Result<(), ANTLRError>
48    where
49        Self: Sized;
50
51    fn precpred(
52        &self,
53        localctx: Option<&TreeNode<'input, 'arena, Self::Node, TF::Tok>>,
54        precedence: i32,
55    ) -> bool;
56
57    fn get_input_stream_mut(&mut self) -> &mut dyn TokenStream<'input, 'arena, TF>;
58    fn get_input_stream(&self) -> &dyn TokenStream<'input, 'arena, TF>;
59    fn get_current_token(&self) -> &'arena TF::Tok;
60    fn get_expected_tokens<'a>(&'a self) -> Cow<'a, IntervalSet>;
61
62    fn add_error_listener(
63        &mut self,
64        listener: Box<dyn ErrorListener<'input, 'arena, Self, TF::Tok> + 'input>,
65    ) where
66        Self: Sized;
67
68    fn remove_error_listeners(&mut self);
69
70    fn notify_error_listeners(
71        &self,
72        msg: String,
73        offending_token: Option<isize>,
74        err: Option<&ANTLRError>,
75    );
76    fn get_error_lister_dispatch<'a>(
77        &'a self,
78    ) -> Box<dyn ErrorListener<'input, 'arena, Self, TF::Tok> + 'a>
79    where
80        Self: Sized;
81
82    fn is_expected_token(&self, symbol: i32) -> bool;
83    fn get_precedence(&self) -> i32;
84
85    fn get_state(&self) -> i32;
86    fn set_state(&mut self, v: i32);
87    fn get_rule_invocation_stack(&self) -> Vec<String>;
88
89    #[cfg(feature = "recursion-limit")]
90    fn get_recursion_limit(&self) -> u32;
91    #[cfg(feature = "recursion-limit")]
92    fn set_recursion_limit(&mut self, v: u32);
93}
94
95/// Abstract base parser implementation
96///
97/// Only meant to be instantiated by generated parsers
98pub struct BaseParser<'input, 'arena, Ext, Node, Input, TF>
99where
100    'input: 'arena,
101    // Grammar-specific implementation of parser functionality required for
102    // `ParserATNSimulator` to work
103    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
104    // Token factory used by the input stream
105    TF: TokenFactory<'input, 'arena> + 'arena,
106    // Token stream (lexer)
107    Input: TokenStream<'input, 'arena, TF>,
108    Node: NodeKindType<'arena, TF::Tok>,
109{
110    interp: Option<ParserATNSimulator<'arena>>,
111    atn_manager: &'static ParserATNSimulatorManager,
112    global_cache_threshold: usize,
113
114    /// Rule context parser is currently processing
115    ctx: *mut (),
116
117    /// Track the {@link ParserRuleContext} objects during the parse and hook
118    /// them up using the {@link ParserRuleContext#children} list so that it
119    /// forms a parse tree. The {@link ParserRuleContext} returned from the start
120    /// rule represents the root of the parse tree.
121    ///
122    /// <p>Note that if we are not building parse trees, rule contexts only point
123    /// upwards. When a rule exits, it returns the context bute that gets garbage
124    /// collected if nobody holds a reference. It points upwards but nobody
125    /// points at it. </p>
126    ///
127    /// <p>When we build parse trees, we are adding all of these contexts to
128    /// {@link ParserRuleContext#children} list. Contexts are then not candidates
129    /// for garbage collection.</p>
130    ///
131    /// Returns {@code true} if a complete parse tree will be constructed while
132    /// parsing, otherwise {@code false}
133    pub build_parse_trees: bool,
134
135    /// true if parser reached EOF
136    pub matched_eof: bool,
137
138    state: i32,
139    /// Token stream that is currently used by this parser
140    pub input: Input,
141    precedence_stack: Vec<i32>,
142    #[cfg(feature = "recursion-limit")]
143    pub recursion_limit: u32,
144    #[cfg(feature = "recursion-limit")]
145    current_recursion_depth: u32,
146
147    parse_listeners: Vec<Box<Node::Listener>>,
148    _syntax_errors: Cell<i32>,
149    error_listeners: Vec<ErrorListenerDelegate<'input, 'arena, Self, TF::Tok>>,
150
151    pub arena: &'arena Arena,
152    ext: Ext,
153    pd: PhantomData<(
154        &'input (),
155        &'arena TF,
156        //        &'arena TreeNode<'input, 'arena, Node, TF::Tok>,
157    )>,
158}
159
160impl<'input, 'arena, Ext, Node, Input, TF> Deref
161    for BaseParser<'input, 'arena, Ext, Node, Input, TF>
162where
163    'input: 'arena,
164    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
165    TF: TokenFactory<'input, 'arena> + 'arena,
166    Input: TokenStream<'input, 'arena, TF>,
167    Node: NodeKindType<'arena, TF::Tok>,
168{
169    type Target = Ext;
170
171    fn deref(&self) -> &Self::Target {
172        &self.ext
173    }
174}
175
176impl<'input, 'arena, Ext, Node, Input, TF> DerefMut
177    for BaseParser<'input, 'arena, Ext, Node, Input, TF>
178where
179    'input: 'arena,
180    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
181    TF: TokenFactory<'input, 'arena> + 'arena,
182    Input: TokenStream<'input, 'arena, TF>,
183    Node: NodeKindType<'arena, TF::Tok>,
184{
185    fn deref_mut(&mut self) -> &mut Self::Target {
186        &mut self.ext
187    }
188}
189
190pub trait ParserRecog<'input, 'arena, R, Tok>: Actions<'input, 'arena, R, Tok>
191where
192    'input: 'arena,
193    R: Recognizer<'input, 'arena, Tok>,
194    Tok: Token + 'input,
195{
196    fn get_atn_simulator_man(&self) -> &'static ParserATNSimulatorManager;
197}
198
199impl<'input, 'arena, Ext, Node, Input, TF> Recognizer<'input, 'arena, TF::Tok>
200    for BaseParser<'input, 'arena, Ext, Node, Input, TF>
201where
202    'input: 'arena,
203    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
204    TF: TokenFactory<'input, 'arena> + 'arena,
205    Input: TokenStream<'input, 'arena, TF>,
206    Node: NodeKindType<'arena, TF::Tok>,
207{
208    type Node = Node;
209
210    fn sempred(
211        &mut self,
212        localctx: Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>>,
213        rule_index: i32,
214        action_index: i32,
215    ) -> bool {
216        Ext::sempred(localctx, rule_index, action_index, self)
217    }
218
219    fn get_rule_names(&self) -> &[&str] {
220        self.ext.get_rule_names()
221    }
222
223    fn get_vocabulary(&self) -> &dyn Vocabulary {
224        self.ext.get_vocabulary()
225    }
226
227    fn get_grammar_file_name(&self) -> &str {
228        self.ext.get_grammar_file_name()
229    }
230
231    fn get_atn(&self) -> &ATN {
232        self.interp.as_ref().unwrap().atn()
233    }
234}
235
236impl<'input, 'arena, Ext, Node, Input, TF> Parser<'input, 'arena, TF>
237    for BaseParser<'input, 'arena, Ext, Node, Input, TF>
238where
239    'input: 'arena,
240    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
241    TF: TokenFactory<'input, 'arena> + 'arena,
242    Input: TokenStream<'input, 'arena, TF>,
243    Node: NodeKindType<'arena, TF::Tok>,
244{
245    fn get_arena(&self) -> &'arena Arena {
246        self.arena
247    }
248
249    #[inline(always)]
250    fn get_interpreter(&self) -> &'arena ParserATNSimulator<'arena> {
251        unsafe {
252            std::mem::transmute::<&ParserATNSimulator<'arena>, &'arena ParserATNSimulator<'arena>>(
253                self.interp.as_ref().unwrap(),
254            )
255        }
256    }
257
258    fn get_token_factory(&self) -> &TF {
259        self.input.get_token_source().get_token_factory()
260    }
261
262    #[inline(always)]
263    fn get_current_context(&self) -> &'arena TreeNode<'input, 'arena, Node, TF::Tok> {
264        self.ctx().unwrap()
265    }
266
267    fn consume(
268        &mut self,
269        err_handler: &mut impl ErrorStrategy<'input, 'arena, TF, Self>,
270    ) -> Result<(), ANTLRError> {
271        let o = self.get_current_token();
272        if o.borrow().get_token_type() != TOKEN_EOF {
273            self.input.consume();
274        }
275        if self.build_parse_trees || !self.parse_listeners.is_empty() {
276            if err_handler.in_error_recovery_mode(self) {
277                // todo report ructc inference issue
278                let node = self.create_error_node(o)?;
279                self.add_child_to_ctx(node);
280                for listener in &mut self.parse_listeners {
281                    listener.visit_error_node(
282                        node.as_error_node()
283                            .expect("node was created as error node"),
284                    )?
285                }
286            } else {
287                let node = self.create_token_node(o)?;
288                self.add_child_to_ctx(node);
289                for listener in &mut self.parse_listeners {
290                    listener.visit_terminal(
291                        node.as_terminal_node()
292                            .expect("node was created as terminal node"),
293                    )?
294                }
295            }
296        }
297        Ok(())
298    }
299
300    fn precpred(
301        &self,
302        _localctx: Option<&TreeNode<'input, 'arena, Node, TF::Tok>>,
303        precedence: i32,
304    ) -> bool {
305        //        localctx.map(|it|println!("check at{}",it.to_string_tree(self)));
306        //        println!("{}",self.get_precedence());
307        precedence >= self.get_precedence()
308    }
309
310    fn get_input_stream_mut(&mut self) -> &mut dyn TokenStream<'input, 'arena, TF> {
311        &mut self.input //.as_mut()
312    }
313
314    fn get_input_stream(&self) -> &dyn TokenStream<'input, 'arena, TF> {
315        &self.input
316    }
317
318    #[inline]
319    fn get_current_token(&self) -> &'arena TF::Tok {
320        self.input.get(self.input.index())
321    }
322
323    fn get_expected_tokens<'a>(&'a self) -> Cow<'a, IntervalSet> {
324        let states_stack = states_stack(self.ctx().unwrap());
325        self.interp
326            .as_ref()
327            .unwrap()
328            .atn()
329            .get_expected_tokens::<TF::Tok>(self.state, states_stack)
330    }
331
332    fn add_error_listener(
333        &mut self,
334        listener: Box<dyn ErrorListener<'input, 'arena, Self, TF::Tok> + 'input>,
335    ) {
336        self.error_listeners
337            .push(ErrorListenerDelegate::new(listener))
338    }
339
340    fn remove_error_listeners(&mut self) {
341        self.error_listeners.clear();
342    }
343
344    fn notify_error_listeners(
345        &self,
346        msg: String,
347        offending_token: Option<isize>,
348        err: Option<&ANTLRError>,
349    ) {
350        cell_update(&self._syntax_errors, |it| it + 1);
351        let offending_token: Option<&_> = match offending_token {
352            None => Some(self.get_current_token().borrow()),
353            Some(x) => Some(self.input.get(x).borrow()),
354        };
355        let line = offending_token.map(|x| x.get_line()).unwrap_or(0);
356        let column = offending_token
357            .map(|x| x.get_char_position_in_line())
358            .unwrap_or(-1);
359
360        for listener in self.error_listeners.iter() {
361            listener.syntax_error(
362                self,
363                offending_token.map(|x| x as _),
364                line,
365                column,
366                &msg,
367                err,
368            )
369        }
370    }
371
372    fn get_error_lister_dispatch<'a>(
373        &'a self,
374    ) -> Box<dyn ErrorListener<'input, 'arena, Self, TF::Tok> + 'a> {
375        Box::new(ProxyErrorListener {
376            delegates: self.error_listeners.borrow(),
377        })
378    }
379
380    fn is_expected_token(&self, _symbol: i32) -> bool {
381        unimplemented!()
382    }
383
384    fn get_precedence(&self) -> i32 {
385        *self.precedence_stack.last().unwrap_or(&-1)
386    }
387
388    #[inline(always)]
389    fn get_state(&self) -> i32 {
390        self.state
391    }
392
393    #[inline(always)]
394    fn set_state(&mut self, v: i32) {
395        self.state = v;
396    }
397
398    fn get_rule_invocation_stack(&self) -> Vec<String> {
399        let mut vec = Vec::new();
400        let rule_names = self.get_rule_names();
401        let mut ctx = self.get_current_context();
402        loop {
403            let rule_index = ctx.get_rule_index();
404            vec.push(rule_names.get(rule_index).unwrap_or(&"n/a").to_string());
405            ctx = if let Some(parent) = ctx.get_parent() {
406                parent
407            } else {
408                break;
409            }
410        }
411        vec
412    }
413
414    #[cfg(feature = "recursion-limit")]
415    fn get_recursion_limit(&self) -> u32 {
416        self.recursion_limit
417    }
418
419    #[cfg(feature = "recursion-limit")]
420    fn set_recursion_limit(&mut self, v: u32) {
421        self.recursion_limit = v;
422    }
423
424    //    fn get_rule_invocation_stack(&self, c: _) -> Vec<String> {
425    //        unimplemented!()
426    //    }
427}
428
429#[allow(missing_docs)] // todo docs
430impl<'input, 'arena, Ext, Node, Input, TF> BaseParser<'input, 'arena, Ext, Node, Input, TF>
431where
432    'input: 'arena,
433    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
434    TF: TokenFactory<'input, 'arena> + 'arena,
435    Input: TokenStream<'input, 'arena, TF>,
436    Node: NodeKindType<'arena, TF::Tok>,
437{
438    pub fn new_base_parser(arena: &'arena Arena, input: Input, ext: Ext) -> Self {
439        let atn_manager = ext.get_atn_simulator_man();
440        let interp = ParserATNSimulator::new(atn_manager.get_simulator(arena));
441        Self {
442            atn_manager,
443            interp: Some(interp),
444            global_cache_threshold: 0,
445            ctx: std::ptr::null_mut(),
446            build_parse_trees: true,
447            matched_eof: false,
448            state: -1,
449            input,
450            precedence_stack: vec![0],
451            #[cfg(feature = "recursion-limit")]
452            recursion_limit: DEFAULT_RECURSION_LIMIT,
453            #[cfg(feature = "recursion-limit")]
454            current_recursion_depth: 0,
455            parse_listeners: vec![],
456            _syntax_errors: Cell::new(0),
457            error_listeners: vec![ErrorListenerDelegate::new(
458                Box::new(ConsoleErrorListener {})
459                    as Box<dyn ErrorListener<'input, 'arena, Self, TF::Tok> + 'input>,
460            )],
461            arena,
462            ext,
463            pd: PhantomData,
464        }
465    }
466
467    pub fn set_global_cache_threshold(&mut self, threshold: usize) {
468        self.global_cache_threshold = threshold;
469    }
470
471    pub fn get_interpreter_mut(&mut self) -> &mut ParserATNSimulator<'arena> {
472        self.interp.as_mut().unwrap()
473    }
474
475    /// If current context is same as the given one by pointer comparison
476    #[inline]
477    pub fn ctx_is(&self, other: Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>>) -> bool {
478        if self.ctx.is_null() && other.is_none() {
479            true
480        } else if self.ctx.is_null() || other.is_none() {
481            false
482        } else {
483            std::ptr::eq(self.ctx, other.unwrap() as *const _ as *const ())
484        }
485    }
486
487    /// Gets a reference to current context.
488    #[inline]
489    pub fn ctx(&self) -> Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>> {
490        if self.ctx.is_null() {
491            None
492        } else {
493            unsafe { Some(&*(self.ctx as *const TreeNode<'input, 'arena, Node, TF::Tok>)) }
494        }
495    }
496
497    /// Gets a mutable reference to current context.
498    ///
499    /// # Safety
500    /// Follows the same safety rules as dereferencing *mut to &mut
501    #[inline]
502    pub unsafe fn ctx_mut(
503        &mut self,
504    ) -> Option<&'arena mut TreeNode<'input, 'arena, Node, TF::Tok>> {
505        if self.ctx.is_null() {
506            None
507        } else {
508            Some(&mut *(self.ctx as *mut TreeNode<'input, 'arena, Node, TF::Tok>))
509        }
510    }
511
512    #[inline]
513    fn parent_ctx(&self) -> Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>> {
514        self.ctx().and_then(|it| it.get_parent())
515    }
516
517    #[inline]
518    fn set_current_ctx(&mut self, ctx: Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>>) {
519        if let Some(ctx) = ctx {
520            self.ctx = ctx as *const TreeNode<'input, 'arena, Node, TF::Tok>
521                as *mut TreeNode<'input, 'arena, Node, TF::Tok> as *mut ();
522        } else {
523            self.ctx = std::ptr::null_mut();
524        }
525    }
526
527    pub fn take_ctx(&mut self) -> Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>> {
528        if self.ctx.is_null() {
529            None
530        } else {
531            let ret = unsafe { &*(self.ctx as *const TreeNode<'input, 'arena, Node, TF::Tok>) };
532            self.ctx = std::ptr::null_mut();
533            Some(ret)
534        }
535    }
536
537    #[inline]
538    fn add_child_to_ctx(&mut self, child: &'arena TreeNode<'input, 'arena, Node, TF::Tok>) {
539        if !self.ctx.is_null() {
540            unsafe {
541                (*(self.ctx as *mut TreeNode<'input, 'arena, Node, TF::Tok>)).add_child(child);
542            }
543        }
544    }
545
546    #[inline]
547    pub fn with_mut_ctx<F, R>(&mut self, f: F) -> R
548    where
549        F: FnOnce(&mut TreeNode<'input, 'arena, Node, TF::Tok>) -> R,
550    {
551        assert!(!self.ctx.is_null());
552        unsafe { f(&mut *(self.ctx as *mut TreeNode<'input, 'arena, Node, TF::Tok>)) }
553    }
554
555    #[inline]
556    pub fn match_token(
557        &mut self,
558        ttype: i32,
559        err_handler: &mut impl ErrorStrategy<'input, 'arena, TF, Self>,
560    ) -> Result<&'arena TF::Tok, ANTLRError> {
561        let mut token = self.get_current_token();
562        if token.get_token_type() == ttype {
563            if ttype == TOKEN_EOF {
564                self.matched_eof = true;
565            }
566
567            err_handler.report_match(self);
568            self.consume(err_handler)?;
569        } else {
570            token = err_handler.recover_inline(self)?;
571            if self.build_parse_trees && token.get_token_index() == -1 {
572                self.add_child_to_ctx(self.create_error_node(token)?);
573            }
574        }
575        Ok(token)
576    }
577
578    #[inline]
579    pub fn match_wildcard(
580        &mut self,
581        err_handler: &mut impl ErrorStrategy<'input, 'arena, TF, Self>,
582    ) -> Result<&'arena TF::Tok, ANTLRError> {
583        let mut token = self.get_current_token();
584        if token.get_token_type() > 0 {
585            err_handler.report_match(self);
586            self.consume(err_handler)?;
587        } else {
588            token = err_handler.recover_inline(self)?;
589            if self.build_parse_trees && token.get_token_index() == -1 {
590                self.add_child_to_ctx(self.create_error_node(token)?);
591            }
592        }
593        Ok(token)
594    }
595
596    /// Adds parse listener for this parser
597    /// returns `listener_id` that can be used later to get listener back
598    ///
599    /// ### Example for listener usage:
600    /// todo
601    pub fn add_dyn_parse_listener(&mut self, listener: Box<Node::Listener>) {
602        self.parse_listeners.push(listener);
603    }
604
605    /// Removes parse listener with corresponding `listener_id`, casts it back to user type and returns it to the caller.
606    /// `listener_id` is returned when listener is added via `add_parse_listener`
607    pub fn remove_parse_listener<L>(&mut self, listener_id: ListenerId<L>) -> Box<L>
608    where
609        L: ParseTreeListener<'arena, Node, TF::Tok>,
610    {
611        let index = self
612            .parse_listeners
613            .iter()
614            .position(|it| ListenerId::new(it).actual_id == listener_id.actual_id)
615            .expect("listener not found");
616        unsafe { listener_id.into_listener(self.parse_listeners.remove(index)) }
617    }
618
619    /// Removes all added parse listeners without returning them
620    pub fn remove_parse_listeners(&mut self) {
621        self.parse_listeners.clear()
622    }
623
624    pub fn trigger_enter_rule_event(&mut self) -> Result<(), ANTLRError> {
625        let ctx = self.ctx().unwrap();
626        for listener in self.parse_listeners.iter_mut() {
627            listener.enter_every_rule(ctx)?;
628            ctx.enter_rule(listener)?;
629        }
630        Ok(())
631    }
632
633    pub fn trigger_exit_rule_event(&mut self) -> Result<(), ANTLRError> {
634        let ctx = self.ctx().unwrap();
635        for listener in self.parse_listeners.iter_mut().rev() {
636            ctx.exit_rule(listener)?;
637            listener.exit_every_rule(ctx)?;
638        }
639        Ok(())
640    }
641
642    //    fn get_atn_with_bypass_alts(&self) { unimplemented!() }
643    //
644    //    fn compile_parse_tree_pattern(&self, pattern, patternRuleIndex: Lexer, lexer: Lexer) { unimplemented!() }
645
646    #[inline]
647    pub fn enter_rule(
648        &mut self,
649        localctx: &'arena mut TreeNode<'input, 'arena, Node, TF::Tok>,
650        state: i32,
651        _rule_index: usize,
652    ) -> Result<(), ANTLRError> {
653        let child = localctx;
654        if self.build_parse_trees {
655            self.set_current_ctx(child.get_parent());
656            self.add_child_to_ctx(child);
657        }
658
659        self.set_state(state);
660        self.set_current_ctx(Some(child));
661        let start = self.input.lt(1);
662        self.with_mut_ctx(|ctx| {
663            ctx.set_start(start);
664        });
665
666        if !self.parse_listeners.is_empty() {
667            self.trigger_enter_rule_event()?;
668        }
669
670        #[cfg(feature = "recursion-limit")]
671        {
672            self.current_recursion_depth += 1;
673            if self.current_recursion_depth > self.recursion_limit {
674                return Err(ANTLRError::recursion_limit_exceeded(self.recursion_limit));
675            }
676        }
677        Ok(())
678    }
679
680    #[inline]
681    pub fn exit_rule(
682        &mut self,
683    ) -> Result<&'arena TreeNode<'input, 'arena, Node, TF::Tok>, ANTLRError> {
684        assert!(self.ctx().is_some());
685
686        #[cfg(feature = "recursion-limit")]
687        {
688            self.current_recursion_depth -= 1;
689        }
690        if self.matched_eof {
691            // if we have matched EOF, it cannot consume past EOF so we use LT(1) here
692            let stop = self.input.lt(1);
693            self.with_mut_ctx(|ctx| {
694                ctx.set_stop(stop);
695            });
696        } else {
697            // stop node is what we just matched
698            let stop = self.input.lt(-1);
699            self.with_mut_ctx(|ctx| {
700                ctx.set_stop(stop);
701            });
702        }
703        if !self.parse_listeners.is_empty() {
704            self.trigger_exit_rule_event()?;
705        }
706
707        self.set_state(self.ctx().unwrap().get_invoking_state());
708        let child = self.ctx().unwrap();
709        self.set_current_ctx(child.get_parent());
710
711        Ok(child)
712    }
713
714    pub fn enter_recursion_rule(
715        &mut self,
716        localctx: &'arena mut TreeNode<'input, 'arena, Node, TF::Tok>,
717        state: i32,
718        _rule_index: usize,
719        precedence: i32,
720    ) -> Result<(), ANTLRError> {
721        self.set_state(state);
722        self.precedence_stack.push(precedence);
723        self.set_current_ctx(Some(localctx));
724        let start = self.input.lt(1);
725        self.with_mut_ctx(|ctx| {
726            ctx.set_start(start);
727        });
728        if !self.parse_listeners.is_empty() {
729            self.trigger_enter_rule_event()?;
730        }
731        //println!("{}",self.input.lt(1).map(Token::to_owned).unwrap());
732
733        #[cfg(feature = "recursion-limit")]
734        {
735            self.current_recursion_depth += 1;
736            if self.current_recursion_depth > self.recursion_limit {
737                return Err(ANTLRError::recursion_limit_exceeded(self.recursion_limit));
738            }
739        }
740        Ok(())
741    }
742
743    pub fn push_new_recursion_context(
744        &mut self,
745        localctx: &'arena mut TreeNode<'input, 'arena, Node, TF::Tok>,
746        state: i32,
747        _rule_index: usize,
748    ) -> Result<&'arena TreeNode<'input, 'arena, Node, TF::Tok>, ANTLRError> {
749        let stop = self.input.lt(-1);
750        self.with_mut_ctx(|ctx| {
751            ctx.set_parent(Some(localctx));
752            ctx.set_invoking_state(state);
753            ctx.set_stop(stop);
754        });
755
756        let prev = self.take_ctx().unwrap();
757        self.set_current_ctx(Some(localctx));
758        let start = prev.get_start_token();
759        self.with_mut_ctx(|ctx| {
760            ctx.set_start(start);
761        });
762        if self.build_parse_trees {
763            self.add_child_to_ctx(prev);
764        }
765        if !self.parse_listeners.is_empty() {
766            self.trigger_enter_rule_event()?;
767        }
768        Ok(prev)
769    }
770
771    pub fn unroll_recursion_context(
772        &mut self,
773        parent_ctx: Option<&'arena TreeNode<'input, 'arena, Node, TF::Tok>>,
774    ) -> Result<&'arena TreeNode<'input, 'arena, Node, TF::Tok>, ANTLRError> {
775        assert!(self.ctx().is_some());
776
777        #[cfg(feature = "recursion-limit")]
778        {
779            self.current_recursion_depth -= 1;
780        }
781        self.precedence_stack.pop();
782        let stop = self.input.lt(-1);
783        self.with_mut_ctx(|ctx| {
784            ctx.set_stop(stop);
785        });
786        let retctx = self.ctx;
787
788        // unroll so _ctx is as it was before call to recursive method
789        if !self.parse_listeners.is_empty() {
790            while !self.ctx_is(parent_ctx) {
791                self.trigger_exit_rule_event()?;
792                self.set_current_ctx(self.parent_ctx());
793            }
794        } else {
795            self.set_current_ctx(parent_ctx);
796        }
797
798        // hook into tree
799        unsafe {
800            (*(retctx as *mut TreeNode<'input, 'arena, Node, TF::Tok>)).set_parent(parent_ctx);
801        }
802
803        //        println!("{:?}",self.ctx.as_ref().map(|it|it.to_string_tree(self)));
804        if self.build_parse_trees && parent_ctx.is_some() {
805            self.add_child_to_ctx(unsafe {
806                &*(retctx as *const TreeNode<'input, 'arena, Node, TF::Tok>)
807            });
808        }
809        Ok(unsafe { &*(retctx as *const TreeNode<'input, 'arena, Node, TF::Tok>) })
810    }
811
812    #[allow(clippy::mut_from_ref)] // &mut is from the arena allocation
813    fn create_token_node(
814        &self,
815        token: &'arena TF::Tok,
816    ) -> Result<&'arena mut TreeNode<'input, 'arena, Node, TF::Tok>, ANTLRError> {
817        let ptr = TreeNode::create_token_node(self.arena, token);
818        if ptr.is_null() {
819            #[cfg(feature = "arena-allocation-limit")]
820            {
821                Err(ANTLRError::arena_allocation_limit_exceeded(
822                    self.arena.allocation_limit_bytes(),
823                    self.arena.total_allocated_bytes(),
824                ))
825            }
826            #[cfg(not(feature = "arena-allocation-limit"))]
827            {
828                std::alloc::handle_alloc_error(std::alloc::Layout::new::<
829                    TreeNode<'input, 'arena, Node, TF::Tok>,
830                >())
831            }
832        } else {
833            Ok(unsafe { &mut *ptr })
834        }
835    }
836
837    #[allow(clippy::mut_from_ref)] // &mut is from the arena allocation
838    fn create_error_node(
839        &self,
840        token: &'arena TF::Tok,
841    ) -> Result<&'arena mut TreeNode<'input, 'arena, Node, TF::Tok>, ANTLRError> {
842        let ptr = TreeNode::create_error_node(self.arena, token);
843        if ptr.is_null() {
844            Err(ANTLRError::dfa_cache_limit_exceeded(0, 0, 0))
845        } else {
846            Ok(unsafe { &mut *ptr })
847        }
848    }
849
850    /// Text representation of generated DFA for debugging purposes
851    pub fn dump_dfa(&self) {
852        let mut seen_one = false;
853        for i in 0..self.get_atn().decision_to_state.len() {
854            let dfa = self
855                .get_interpreter()
856                .decision_to_dfa(i)
857                .expect("dfa should exist for each decision");
858            if !dfa.is_empty() {
859                if seen_one {
860                    println!()
861                }
862                println!("Decision {}:", dfa.decision);
863                print!("{}", dfa.to_string(self.get_vocabulary()));
864                seen_one = true;
865            }
866        }
867    }
868}
869
870impl<'input, 'arena, Ext, Node, Input, TF> Drop for BaseParser<'input, 'arena, Ext, Node, Input, TF>
871where
872    'input: 'arena,
873    Ext: ParserRecog<'input, 'arena, Self, TF::Tok>,
874    TF: TokenFactory<'input, 'arena> + 'arena,
875    Input: TokenStream<'input, 'arena, TF>,
876    Node: NodeKindType<'arena, TF::Tok>,
877{
878    fn drop(&mut self) {
879        if self.global_cache_threshold == 0 {
880            return;
881        }
882
883        let Some(interp) = self.interp.take() else {
884            return;
885        };
886        let cache_bytes = interp.total_allocated_bytes();
887        drop(interp);
888
889        if cache_bytes > self.global_cache_threshold {
890            self.atn_manager.reset_all();
891        }
892    }
893}
894
895/// Allows to safely cast listener back to user type
896#[derive(Debug)]
897pub struct ListenerId<T: ?Sized> {
898    pub(crate) actual_id: usize,
899    phantom: PhantomData<fn() -> T>,
900}
901
902impl<T: ?Sized> ListenerId<T> {
903    #[allow(clippy::borrowed_box)]
904    pub fn new(listener: &Box<T>) -> ListenerId<T> {
905        ListenerId {
906            actual_id: listener.as_ref() as *const T as *const () as usize,
907            phantom: Default::default(),
908        }
909    }
910}
911
912impl<T> ListenerId<T> {
913    unsafe fn into_listener<U: ?Sized>(self, boxed: Box<U>) -> Box<T> {
914        Box::from_raw(Box::into_raw(boxed) as *mut T)
915    }
916}