Skip to main content

dbt_antlr4/
parser.rs

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