Skip to main content

dbt_antlr4/
rule_context.rs

1//! Minimal parser node
2use std::borrow::{Borrow, BorrowMut};
3use std::fmt::{Debug, Formatter};
4use std::iter::from_fn;
5use std::marker::PhantomData;
6
7use crate::atn::INVALID_ALT;
8use crate::errors::ANTLRError;
9use crate::parser_rule_context::{
10    BaseParserRuleContext, EmptyParserRuleContext, ParserRuleContext,
11};
12use crate::token::{CommonToken, Token};
13use crate::tree::{
14    ErrorNode, NodeInner, NodeKindType, ParseTreeListener, TerminalNode, Tree, TreeNode,
15};
16use crate::{
17    impl_node_inner, impl_node_kind, impl_parser_rule_context, impl_rule_context,
18    impl_tree_trait_delegates,
19};
20use std::any::type_name;
21
22/// Language-agnostic, dyn-compatible, read-only interface to the AST.
23pub trait RuleContext<'arena> {
24    /// Internal parser state
25    fn get_invoking_state(&self) -> i32;
26
27    /// A context is empty if there is no invoking state; meaning nobody called
28    /// current context. Which is usually true for the root of the syntax tree
29    fn is_empty(&self) -> bool {
30        self.get_invoking_state() == -1
31    }
32
33    /// Get parent context
34    fn get_parent_ctx(&self) -> Option<&'arena dyn RuleContext<'arena>>;
35
36    /// Rule index that corresponds to this context type
37    fn get_rule_index(&self) -> usize;
38
39    fn get_alt_number(&self) -> i32;
40
41    /// Returns text representation of current node type,
42    /// rule name for context nodes and token text for terminal nodes
43    fn get_node_text(&self, rule_names: &[&str]) -> String;
44}
45
46pub(crate) fn states_stack<'input, 'arena, Node, Tok>(
47    mut node: &'arena TreeNode<'input, 'arena, Node, Tok>,
48) -> impl Iterator<Item = i32> + 'arena
49where
50    'input: 'arena,
51    Tok: Token + 'input,
52    Node: NodeKindType<'arena, Tok> + 'arena,
53{
54    from_fn(move || {
55        if node.get_invoking_state() < 0 {
56            None
57        } else {
58            let state = node.get_invoking_state();
59            node = Tree::get_parent(node).unwrap();
60            Some(state)
61        }
62    })
63}
64
65/// Implemented by generated parser for context extension for particular rule
66#[allow(missing_docs)]
67pub trait CustomRuleContext<'input, 'arena, Tok>: Debug + Sized
68where
69    'input: 'arena,
70    Tok: Token + 'input,
71{
72    type NodeKind: NodeKindType<'arena, Tok>;
73
74    fn node_tag() -> Self::NodeKind;
75
76    fn make_node(
77        arena: &'arena crate::arena::Arena,
78        ctx: BaseParserRuleContext<'input, 'arena, Self, Self::NodeKind, Tok>,
79    ) -> *mut TreeNode<'input, 'arena, Self::NodeKind, Tok>;
80
81    fn cast_from<'a>(
82        node: &'a TreeNode<'input, 'arena, Self::NodeKind, Tok>,
83    ) -> Option<&'a BaseParserRuleContext<'input, 'arena, Self, Self::NodeKind, Tok>>;
84
85    fn cast_from_mut<'a>(
86        node: &'a mut TreeNode<'input, 'arena, Self::NodeKind, Tok>,
87    ) -> Option<&'a mut BaseParserRuleContext<'input, 'arena, Self, Self::NodeKind, Tok>>;
88
89    /// Rule index that corresponds to this context type
90    fn get_rule_index(&self) -> usize;
91
92    /// For rule associated with this parse tree internal node, return the outer
93    /// alternative number used to match the input. Default implementation does
94    /// not compute nor store this alt num. Create a subclass of
95    /// ParserRuleContext with backing field and set option contextSuperClass.
96    /// to set it.
97    ///
98    /// @since 4.5.3
99    fn get_alt_number(&self) -> i32 {
100        INVALID_ALT
101    }
102
103    /// Set the outer alternative number for this context node. Default
104    /// implementation does nothing to avoid backing field overhead for trees
105    /// that don't need it.  Create a subclass of ParserRuleContext with backing
106    /// field and set option contextSuperClass.
107    ///
108    /// @since 4.5.3
109    fn set_alt_number(&mut self, _alt_number: i32) {}
110
111    /// Returns text representation of current node type,
112    /// rule name for context nodes and token text for terminal nodes
113    fn get_node_text(&self, rule_names: &[&str]) -> String {
114        let rule_index = self.get_rule_index();
115        let rule_name = rule_names[rule_index];
116        let alt_number = self.get_alt_number();
117        if alt_number != INVALID_ALT {
118            return format!("{}:{}", rule_name, alt_number);
119        }
120        rule_name.to_owned()
121    }
122}
123
124#[derive(Debug, Default)]
125#[doc(hidden)]
126pub struct EmptyCustomRuleContext<'input, 'arena>(
127    pub(crate) PhantomData<(&'input (), *mut &'arena ())>,
128);
129
130#[derive(Clone, Copy, PartialEq, Eq, Debug)]
131#[repr(u16)]
132pub enum EmptyNodeKind {
133    EmptyContext,
134    Terminal,
135    Error,
136}
137
138impl_node_kind! {EmptyNodeKind { EmptyContext(EmptyContextAll),; }; }
139
140#[derive(Debug)]
141#[repr(u16)]
142pub enum EmptyContextAll<'input, 'arena, Tok: Token = CommonToken<'input>> {
143    EmptyContext(EmptyParserRuleContext<'input, 'arena, Tok>),
144    Error(EmptyParserRuleContext<'input, 'arena, Tok>),
145}
146
147impl_node_inner!(EmptyNodeKind::EmptyContext::EmptyContextAll {
148    EmptyContext,
149    Error,
150});
151impl_tree_trait_delegates!(EmptyNodeKind::EmptyContextAll {
152    EmptyContext,
153    Error,
154});
155impl_rule_context!(EmptyContextAll {} { EmptyContext, Error, });
156impl_parser_rule_context!(EmptyContextAll {} { EmptyContext, Error, });
157//impl_listener_dispatch!( EmptyListener::EmptyNodeKind::EmptyContextAll { EmptyContext(enter_empty, exit_empty), });
158
159pub type EmptyRuleNode<'input, 'arena, Tok = CommonToken<'input>> =
160    TreeNode<'input, 'arena, EmptyNodeKind, Tok>;
161
162pub trait EmptyListener<'arena, Tok: Token + 'arena>:
163    ParseTreeListener<'arena, EmptyNodeKind, Tok>
164{
165    fn enter_empty<'input>(
166        &mut self,
167        _ctx: &EmptyParserRuleContext<'input, 'arena>,
168    ) -> Result<(), ANTLRError> {
169        Ok(())
170    }
171
172    fn exit_empty<'input>(
173        &mut self,
174        _ctx: &EmptyParserRuleContext<'input, 'arena>,
175    ) -> Result<(), ANTLRError> {
176        Ok(())
177    }
178}
179
180pub trait EmptyVisitor<'input, 'arena>
181where
182    'input: 'arena,
183{
184    type Return: Default;
185
186    fn visit<Tok: Token + 'input>(
187        &mut self,
188        node: &EmptyRuleNode<'input, 'arena, Tok>,
189    ) -> Result<Self::Return, ANTLRError>;
190
191    /// Called on terminal(leaf) node
192    fn visit_terminal(
193        &mut self,
194        _node: &TerminalNode<'input, 'arena>,
195    ) -> Result<Self::Return, ANTLRError> {
196        Ok(Self::Return::default())
197    }
198
199    /// Called on error node
200    fn visit_error_node(
201        &mut self,
202        _node: &ErrorNode<'input, 'arena>,
203    ) -> Result<Self::Return, ANTLRError> {
204        Ok(Self::Return::default())
205    }
206
207    fn visit_children<Tok: Token + 'input>(
208        &mut self,
209        node: &dyn NodeInner<'input, 'arena, EmptyNodeKind, Tok>,
210    ) -> Result<Self::Return, ANTLRError> {
211        let mut result = Self::Return::default();
212        for child in node.iter_child_nodes() {
213            if !self.should_visit_next_child(child, &result) {
214                break;
215            }
216
217            let child_result = self.visit(child)?;
218            result = self.aggregate_results(result, child_result)?;
219        }
220        Ok(result)
221    }
222
223    fn aggregate_results(
224        &self,
225        _aggregate: Self::Return,
226        next: Self::Return,
227    ) -> Result<Self::Return, ANTLRError> {
228        Ok(next)
229    }
230
231    fn should_visit_next_child<Tok: Token + 'input>(
232        &self,
233        _node: &EmptyRuleNode<'input, 'arena, Tok>,
234        _current: &Self::Return,
235    ) -> bool {
236        true
237    }
238
239    fn visit_empty<Tok: Token + 'input>(
240        &mut self,
241        ctx: &EmptyParserRuleContext<'input, 'arena, Tok>,
242    ) -> Result<Self::Return, ANTLRError> {
243        self.visit_children(ctx)
244    }
245}
246
247pub trait Visitable<'input, 'arena>
248where
249    'input: 'arena,
250{
251    fn accept<V>(
252        &'arena self,
253        visitor: &mut V,
254    ) -> Result<<V as EmptyVisitor<'input, 'arena>>::Return, ANTLRError>
255    where
256        V: EmptyVisitor<'input, 'arena> + ?Sized;
257}
258
259// impl_rule_node!(EmptyRuleNode { ; Empty(enter_empty, exit_empty, visit_empty), }; listener = dyn EmptyListener<'input, 'arena>, visitor = EmptyVisitor, );
260
261// impl_defaults!(EmptyRuleNode);
262
263impl<'input, 'arena, Tok> CustomRuleContext<'input, 'arena, Tok>
264    for EmptyCustomRuleContext<'input, 'arena>
265where
266    'input: 'arena,
267    Tok: Token + 'input,
268{
269    type NodeKind = EmptyNodeKind;
270
271    fn node_tag() -> EmptyNodeKind {
272        EmptyNodeKind::EmptyContext
273    }
274
275    fn get_rule_index(&self) -> usize {
276        usize::MAX
277    }
278
279    fn make_node(
280        arena: &'arena crate::arena::Arena,
281        ctx: BaseParserRuleContext<'input, 'arena, Self, Self::NodeKind, Tok>,
282    ) -> *mut TreeNode<'input, 'arena, EmptyNodeKind, Tok> {
283        arena.alloc_labeled_node(EmptyContextAll::EmptyContext(ctx))
284    }
285
286    fn cast_from<'a>(
287        node: &'a TreeNode<'input, 'arena, Self::NodeKind, Tok>,
288    ) -> Option<&'a BaseParserRuleContext<'input, 'arena, Self, Self::NodeKind, Tok>> {
289        if node.node_tag == <Self as CustomRuleContext<'input, 'arena, Tok>>::node_tag() {
290            let ctx =
291                unsafe { &*(node as *const _ as *const EmptyContextAll<'input, 'arena, Tok>) };
292            match ctx {
293                EmptyContextAll::EmptyContext(ctx) => Some(ctx),
294                EmptyContextAll::Error(ctx) => Some(ctx),
295            }
296        } else {
297            None
298        }
299    }
300
301    fn cast_from_mut<'a>(
302        node: &'a mut TreeNode<'input, 'arena, Self::NodeKind, Tok>,
303    ) -> Option<&'a mut BaseParserRuleContext<'input, 'arena, Self, Self::NodeKind, Tok>> {
304        if node.node_tag == <Self as CustomRuleContext<'input, 'arena, Tok>>::node_tag() {
305            let ctx =
306                unsafe { &mut *(node as *mut _ as *mut EmptyContextAll<'input, 'arena, Tok>) };
307            match ctx {
308                EmptyContextAll::EmptyContext(ctx) => Some(ctx),
309                EmptyContextAll::Error(ctx) => Some(ctx),
310            }
311        } else {
312            None
313        }
314    }
315}
316
317pub type EmptyRuleContext<'input, 'arena> =
318    BaseRuleContext<'input, 'arena, EmptyCustomRuleContext<'input, 'arena>, EmptyNodeKind>;
319
320/// Core rule context implementation -- this defines the minimal set of states
321/// required for the Antlr parsing algorithm to function.
322///
323/// This is the Rust version of the `RuleContext` "abstract base class", it will
324/// be specialized into language-specific concrete types by monomorphizing the
325/// `ExtCtx` type parameter, which is implemented by generated code.
326#[repr(C)]
327pub struct BaseRuleContext<'input, 'arena, Ext, NodeKind, Tok = CommonToken<'input>>
328where
329    'input: 'arena,
330    NodeKind: NodeKindType<'arena, Tok>,
331    Ext: CustomRuleContext<'input, 'arena, Tok, NodeKind = NodeKind>,
332    Tok: Token + 'input,
333{
334    parent: Option<&'arena TreeNode<'input, 'arena, NodeKind, Tok>>,
335    pub(crate) ext: Ext,
336
337    // Covariant over 'input, invariant over 'arena
338    _marker: PhantomData<(&'input (), *mut &'arena ())>,
339}
340
341#[allow(missing_docs)]
342impl<'input, 'arena, Ext, NodeKind, Tok> BaseRuleContext<'input, 'arena, Ext, NodeKind, Tok>
343where
344    'input: 'arena,
345    NodeKind: NodeKindType<'arena, Tok>,
346    Ext: CustomRuleContext<'input, 'arena, Tok, NodeKind = NodeKind>,
347    Tok: Token + 'input,
348{
349    pub(crate) fn new(
350        parent: Option<&'arena TreeNode<'input, 'arena, NodeKind, Tok>>,
351        ext: Ext,
352    ) -> Self {
353        Self {
354            parent,
355            ext,
356            _marker: PhantomData,
357        }
358    }
359
360    pub(crate) fn morph<Tgt>(
361        self,
362        ctor: impl FnOnce(Ext) -> Tgt,
363    ) -> BaseRuleContext<'input, 'arena, Tgt, NodeKind, Tok>
364    where
365        Tgt: CustomRuleContext<'input, 'arena, Tok, NodeKind = NodeKind>,
366    {
367        BaseRuleContext {
368            parent: self.parent,
369            ext: ctor(self.ext),
370            _marker: PhantomData,
371        }
372    }
373
374    #[inline]
375    pub fn parent(&self) -> Option<&'arena TreeNode<'input, 'arena, NodeKind, Tok>> {
376        self.parent
377    }
378
379    #[inline]
380    pub fn has_parent(&self) -> bool {
381        self.parent.is_some()
382    }
383
384    pub(crate) fn set_parent(
385        &mut self,
386        parent: Option<&'arena TreeNode<'input, 'arena, NodeKind, Tok>>,
387    ) {
388        self.parent = parent;
389    }
390
391    pub(crate) fn set_alt_number(&mut self, _alt_number: i32) {
392        self.ext.set_alt_number(_alt_number)
393    }
394
395    pub(crate) fn get_alt_number(&self) -> i32 {
396        self.ext.get_alt_number()
397    }
398
399    pub(crate) fn get_rule_index(&self) -> usize {
400        self.ext.get_rule_index()
401    }
402
403    pub(crate) fn get_node_text(&self, rule_names: &[&str]) -> String {
404        self.ext.get_node_text(rule_names)
405    }
406}
407
408impl<'input, 'arena, Ext, NodeKind, Tok> Borrow<Ext>
409    for BaseRuleContext<'input, 'arena, Ext, NodeKind, Tok>
410where
411    'input: 'arena,
412    NodeKind: NodeKindType<'arena, Tok>,
413    Ext: CustomRuleContext<'input, 'arena, Tok, NodeKind = NodeKind>,
414    Tok: Token + 'input,
415{
416    fn borrow(&self) -> &Ext {
417        &self.ext
418    }
419}
420
421impl<'input, 'arena, Ext, NodeKind, Tok> BorrowMut<Ext>
422    for BaseRuleContext<'input, 'arena, Ext, NodeKind, Tok>
423where
424    'input: 'arena,
425    NodeKind: NodeKindType<'arena, Tok>,
426    Ext: CustomRuleContext<'input, 'arena, Tok, NodeKind = NodeKind>,
427    Tok: Token + 'input,
428{
429    fn borrow_mut(&mut self) -> &mut Ext {
430        &mut self.ext
431    }
432}
433
434// impl<'input, 'arena, Ext> RuleContext<'arena> for BaseRuleContext<'input, 'arena, Ext>
435// where
436//     'input: 'arena,
437//     Ext: CustomRuleContext<'arena> + 'arena,
438// {
439//     #[inline(always)]
440//     fn get_invoking_state(&self) -> i32 {
441//         self.invoking_state
442//     }
443
444//     fn get_parent_ctx(&self) -> Option<&'arena dyn RuleContext<'arena>> {
445//         self.parent
446//             .map(|rc| rc.get_rule_context() as &dyn RuleContext<'arena>)
447//     }
448
449//     fn get_rule_index(&self) -> usize {
450//         self.ext.get_rule_index()
451//     }
452
453//     fn get_alt_number(&self) -> i32 {
454//         self.ext.get_alt_number()
455//     }
456
457//     fn is_empty(&self) -> bool {
458//         self.get_invoking_state() == -1
459//     }
460
461//     fn get_node_text(&self, rule_names: &[&str]) -> String {
462//         self.ext.get_node_text(rule_names)
463//     }
464// }
465
466impl<'input, 'arena, Ext, NodeKind, Tok> Debug
467    for BaseRuleContext<'input, 'arena, Ext, NodeKind, Tok>
468where
469    'input: 'arena,
470    NodeKind: NodeKindType<'arena, Tok>,
471    Ext: CustomRuleContext<'input, 'arena, Tok, NodeKind = NodeKind>,
472    Tok: Token + 'input,
473{
474    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
475        f.debug_struct(type_name::<Self>())
476            .field("parent", &self.parent)
477            .field("ext", &self.ext)
478            .field("..", &"..")
479            .finish()
480    }
481}