Skip to main content

parser/
arena.rs

1//! Arena allocator for AST nodes. Generated by CongoCC Parser Generator. Do not edit.
2
3use crate::tokens::Token;
4use std::fmt;
5
6/// Type-safe index for nodes in the arena
7#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct NodeId(pub usize);
10impl fmt::Display for NodeId {
11    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12        write!(f, "NodeId({})", self.0)
13    }
14}
15
16/// Type-safe index for tokens in the arena
17#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct TokenId(pub usize);
20
21/// Arena that owns all AST nodes and tokens
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23pub struct Arena {
24    /// All AST nodes
25    nodes: Vec<AstNode>,
26    /// All tokens
27    tokens: Vec<Token>,
28}
29
30impl Arena {
31    /// Create a new empty arena
32    pub fn new() -> Self {
33        Arena {
34            nodes: Vec::new(),
35            tokens: Vec::new(),
36        }
37    }
38
39    /// Allocate a new node in the arena
40    pub fn alloc_node(&mut self, node: AstNode) -> NodeId {
41        let id = NodeId(self.nodes.len());
42        self.nodes.push(node);
43        id
44    }
45
46    /// Get a reference to a node
47    pub fn get_node(&self, id: NodeId) -> &AstNode {
48        &self.nodes[id.0]
49    }
50
51    /// Get a mutable reference to a node
52    pub fn get_node_mut(&mut self, id: NodeId) -> &mut AstNode {
53        &mut self.nodes[id.0]
54    }
55
56    /// Allocate a new token in the arena
57    pub fn alloc_token(&mut self, token: Token) -> TokenId {
58        let id = TokenId(self.tokens.len());
59        self.tokens.push(token);
60        id
61    }
62
63    /// Get a reference to a token
64    pub fn get_token(&self, id: TokenId) -> &Token {
65        &self.tokens[id.0]
66    }
67
68    /// Pretty print the AST starting from the given node
69    pub fn pretty_print(&self, root: NodeId, indent: usize, input: &str) -> String {
70        let mut result = format!("AST: \"{}\"\n", input);
71        self.pretty_print_impl(root, indent + 1, &mut result);
72        result
73    }
74
75    /// Check if a node is a pass-through (single child, no semantic value)
76    fn is_passthrough(&self, node_id: NodeId) -> bool {
77        match self.get_node(node_id) {
78            AstNode::JmsSelector(n) => n.children.len() == 1,
79            AstNode::OrExpression(n) => n.children.len() == 1,
80            AstNode::AndExpression(n) => n.children.len() == 1,
81            AstNode::EqualityExpression(n) => n.children.len() == 1 && n.operators.is_empty(),
82            AstNode::ComparisonExpression(n) => n.children.len() == 1 && n.operators.is_empty(),
83            AstNode::AddExpression(n) => n.children.len() == 1 && n.operators.is_empty(),
84            AstNode::MultExpr(n) => n.children.len() == 1 && n.operators.is_empty(),
85            AstNode::UnaryExpr(n) => n.children.len() == 1 && n.operator.is_none(),
86            AstNode::PrimaryExpr(_) => false,
87            AstNode::Literal(_) => false,
88            AstNode::StringLiteral(n) => n.children.len() == 1,
89            AstNode::Variable(n) => n.children.len() == 1,
90        }
91    }
92
93    /// Get the first child of a node (if any)
94    fn first_child(&self, node_id: NodeId) -> Option<NodeId> {
95        match self.get_node(node_id) {
96            AstNode::JmsSelector(n) => n.children.first().copied(),
97            AstNode::OrExpression(n) => n.children.first().copied(),
98            AstNode::AndExpression(n) => n.children.first().copied(),
99            AstNode::EqualityExpression(n) => n.children.first().copied(),
100            AstNode::ComparisonExpression(n) => n.children.first().copied(),
101            AstNode::AddExpression(n) => n.children.first().copied(),
102            AstNode::MultExpr(n) => n.children.first().copied(),
103            AstNode::UnaryExpr(n) => n.children.first().copied(),
104            AstNode::PrimaryExpr(n) => n.children.first().copied(),
105            AstNode::Literal(n) => n.children.first().copied(),
106            AstNode::StringLiteral(n) => n.children.first().copied(),
107            AstNode::Variable(n) => n.children.first().copied(),
108        }
109    }
110
111    fn pretty_print_impl(&self, node_id: NodeId, indent: usize, result: &mut String) {
112        // Skip pass-through nodes
113        if self.is_passthrough(node_id) {
114            if let Some(child) = self.first_child(node_id) {
115                self.pretty_print_impl(child, indent, result);
116            }
117            return;
118        }
119
120        let indent_str = "  ".repeat(indent);
121        match self.get_node(node_id) {
122            AstNode::JmsSelector(node) => {
123                if node.children.is_empty() {
124                    let value = &self.get_token(node.begin_token).image;
125                    result.push_str(&format!("{}JmsSelector(\"{}\")\n", indent_str, value));
126                } else {
127                    result.push_str(&format!("{}JmsSelector\n", indent_str));
128                    for child in &node.children {
129                        self.pretty_print_impl(*child, indent + 1, result);
130                    }
131                }
132            }
133            AstNode::OrExpression(node) => {
134                if node.children.len() > 1 {
135                    result.push_str(&format!("{}OrExpression [OR x{}]\n", indent_str, node.children.len() - 1));
136                } else {
137                    result.push_str(&format!("{}OrExpression\n", indent_str));
138                }
139                for child in &node.children {
140                    self.pretty_print_impl(*child, indent + 1, result);
141                }
142            }
143            AstNode::AndExpression(node) => {
144                if node.children.len() > 1 {
145                    result.push_str(&format!("{}AndExpression [AND x{}]\n", indent_str, node.children.len() - 1));
146                } else {
147                    result.push_str(&format!("{}AndExpression\n", indent_str));
148                }
149                for child in &node.children {
150                    self.pretty_print_impl(*child, indent + 1, result);
151                }
152            }
153            AstNode::EqualityExpression(node) => {
154                if !node.operators.is_empty() {
155                    let ops: Vec<&str> = node.operators.iter()
156                        .map(|op| match op {
157                            EqualityOp::Equal => "=",
158                            EqualityOp::NotEqual => "<>",
159                            EqualityOp::IsNull => "IS NULL",
160                            EqualityOp::IsNotNull => "IS NOT NULL",
161                        })
162                        .collect();
163                    result.push_str(&format!("{}EqualityExpression [{}]\n", indent_str, ops.join(", ")));
164                } else if node.children.is_empty() {
165                    let value = &self.get_token(node.begin_token).image;
166                    result.push_str(&format!("{}EqualityExpression(\"{}\")\n", indent_str, value));
167                } else {
168                    result.push_str(&format!("{}EqualityExpression\n", indent_str));
169                }
170                for child in &node.children {
171                    self.pretty_print_impl(*child, indent + 1, result);
172                }
173            }
174            AstNode::ComparisonExpression(node) => {
175                if !node.operators.is_empty() {
176                    let ops: Vec<&str> = node.operators.iter()
177                        .map(|op| match op {
178                            ComparisonOp::GreaterThan => ">",
179                            ComparisonOp::GreaterThanEqual => ">=",
180                            ComparisonOp::LessThan => "<",
181                            ComparisonOp::LessThanEqual => "<=",
182                            ComparisonOp::Like => "LIKE",
183                            ComparisonOp::NotLike => "NOT LIKE",
184                            ComparisonOp::LikeEscape => "LIKE ESCAPE",
185                            ComparisonOp::NotLikeEscape => "NOT LIKE ESCAPE",
186                            ComparisonOp::Between => "BETWEEN",
187                            ComparisonOp::NotBetween => "NOT BETWEEN",
188                            ComparisonOp::In => "IN",
189                            ComparisonOp::NotIn => "NOT IN",
190                        })
191                        .collect();
192                    result.push_str(&format!("{}ComparisonExpression [{}]\n", indent_str, ops.join(", ")));
193                } else if node.children.is_empty() {
194                    let value = &self.get_token(node.begin_token).image;
195                    result.push_str(&format!("{}ComparisonExpression(\"{}\")\n", indent_str, value));
196                } else {
197                    result.push_str(&format!("{}ComparisonExpression\n", indent_str));
198                }
199                for child in &node.children {
200                    self.pretty_print_impl(*child, indent + 1, result);
201                }
202            }
203            AstNode::AddExpression(node) => {
204                if !node.operators.is_empty() {
205                    let ops: Vec<&str> = node.operators.iter()
206                        .map(|op| match op {
207                            AddOp::Plus => "+",
208                            AddOp::Minus => "-",
209                        })
210                        .collect();
211                    result.push_str(&format!("{}AddExpression [{}]\n", indent_str, ops.join(", ")));
212                } else {
213                    result.push_str(&format!("{}AddExpression\n", indent_str));
214                }
215                for child in &node.children {
216                    self.pretty_print_impl(*child, indent + 1, result);
217                }
218            }
219            AstNode::MultExpr(node) => {
220                if !node.operators.is_empty() {
221                    let ops: Vec<&str> = node.operators.iter()
222                        .map(|op| match op {
223                            MultExprOp::Star => "*",
224                            MultExprOp::Slash => "/",
225                            MultExprOp::Percent => "%",
226                        })
227                        .collect();
228                    result.push_str(&format!("{}MultExpr [{}]\n", indent_str, ops.join(", ")));
229                } else {
230                    result.push_str(&format!("{}MultExpr\n", indent_str));
231                }
232                for child in &node.children {
233                    self.pretty_print_impl(*child, indent + 1, result);
234                }
235            }
236            AstNode::UnaryExpr(node) => {
237                if let Some(op) = &node.operator {
238                    let op_str = match op {
239                        UnaryOp::Plus => "+",
240                        UnaryOp::Negate => "-",
241                        UnaryOp::Not => "NOT",
242                    };
243                    result.push_str(&format!("{}UnaryExpr [{}]\n", indent_str, op_str));
244                } else if node.children.is_empty() {
245                    let value = &self.get_token(node.begin_token).image;
246                    result.push_str(&format!("{}UnaryExpr(\"{}\")\n", indent_str, value));
247                } else {
248                    result.push_str(&format!("{}UnaryExpr\n", indent_str));
249                }
250                for child in &node.children {
251                    self.pretty_print_impl(*child, indent + 1, result);
252                }
253            }
254            AstNode::PrimaryExpr(node) => {
255                if node.children.is_empty() {
256                    let token = self.get_token(node.begin_token);
257                    result.push_str(&format!("{}PrimaryExpr(\"{}\")\n", indent_str, token.image));
258                } else {
259                    result.push_str(&format!("{}PrimaryExpr\n", indent_str));
260                    for child in &node.children {
261                        self.pretty_print_impl(*child, indent + 1, result);
262                    }
263                }
264            }
265            AstNode::Literal(node) => {
266                if node.children.is_empty() {
267                    let token = self.get_token(node.begin_token);
268                    result.push_str(&format!("{}Literal(\"{}\")\n", indent_str, token.image));
269                } else {
270                    result.push_str(&format!("{}Literal\n", indent_str));
271                    for child in &node.children {
272                        self.pretty_print_impl(*child, indent + 1, result);
273                    }
274                }
275            }
276            AstNode::StringLiteral(node) => {
277                if node.children.is_empty() {
278                    let value = &self.get_token(node.begin_token).image;
279                    result.push_str(&format!("{}StringLiteral(\"{}\")\n", indent_str, value));
280                } else {
281                    result.push_str(&format!("{}StringLiteral\n", indent_str));
282                    for child in &node.children {
283                        self.pretty_print_impl(*child, indent + 1, result);
284                    }
285                }
286            }
287            AstNode::Variable(node) => {
288                if node.children.is_empty() {
289                    let value = &self.get_token(node.begin_token).image;
290                    result.push_str(&format!("{}Variable(\"{}\")\n", indent_str, value));
291                } else {
292                    result.push_str(&format!("{}Variable\n", indent_str));
293                    for child in &node.children {
294                        self.pretty_print_impl(*child, indent + 1, result);
295                    }
296                }
297            }
298        }
299    }
300}
301
302impl Default for Arena {
303    fn default() -> Self {
304        Self::new()
305    }
306}
307
308/// Enum containing all AST node types
309#[derive(Debug, Clone)]
310#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
311pub enum AstNode {
312    /// AST node: JmsSelector
313    JmsSelector(JmsSelectorNode),
314    /// AST node: orExpression
315    OrExpression(OrExpressionNode),
316    /// AST node: andExpression
317    AndExpression(AndExpressionNode),
318    /// AST node: equalityExpression
319    EqualityExpression(EqualityExpressionNode),
320    /// AST node: comparisonExpression
321    ComparisonExpression(ComparisonExpressionNode),
322    /// AST node: addExpression
323    AddExpression(AddExpressionNode),
324    /// AST node: multExpr
325    MultExpr(MultExprNode),
326    /// AST node: unaryExpr
327    UnaryExpr(UnaryExprNode),
328    /// AST node: primaryExpr
329    PrimaryExpr(PrimaryExprNode),
330    /// AST node: literal
331    Literal(LiteralNode),
332    /// AST node: stringLiteral
333    StringLiteral(StringLiteralNode),
334    /// AST node: variable
335    Variable(VariableNode),
336}
337
338/// Operator for addExpression
339#[derive(Debug, Clone, Copy, PartialEq, Eq)]
340#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
341pub enum AddOp {
342    /// +
343    Plus,
344    /// -
345    Minus,
346}
347
348/// Operator for multExpr
349#[derive(Debug, Clone, Copy, PartialEq, Eq)]
350#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
351pub enum MultExprOp {
352    /// *
353    Star,
354    /// /
355    Slash,
356    /// %
357    Percent,
358}
359
360/// Operator for equalityExpression
361#[derive(Debug, Clone, Copy, PartialEq, Eq)]
362#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
363pub enum EqualityOp {
364    /// =
365    Equal,
366    /// <>
367    NotEqual,
368    /// IS NULL
369    IsNull,
370    /// IS NOT NULL
371    IsNotNull,
372}
373
374/// Operator for comparisonExpression
375#[derive(Debug, Clone, Copy, PartialEq, Eq)]
376#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
377pub enum ComparisonOp {
378    /// >
379    GreaterThan,
380    /// >=
381    GreaterThanEqual,
382    /// <
383    LessThan,
384    /// <=
385    LessThanEqual,
386    /// LIKE
387    Like,
388    /// NOT LIKE
389    NotLike,
390    /// LIKE with ESCAPE clause
391    LikeEscape,
392    /// NOT LIKE with ESCAPE clause
393    NotLikeEscape,
394    /// BETWEEN
395    Between,
396    /// NOT BETWEEN
397    NotBetween,
398    /// IN
399    In,
400    /// NOT IN
401    NotIn,
402}
403
404/// Operator for unaryExpr
405#[derive(Debug, Clone, Copy, PartialEq, Eq)]
406#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
407pub enum UnaryOp {
408    /// +
409    Plus,
410    /// -
411    Negate,
412    /// NOT
413    Not,
414}
415
416/// AST node for JmsSelector production
417#[derive(Debug, Clone)]
418#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
419pub struct JmsSelectorNode {
420    /// Parent node (if any)
421    pub parent: Option<NodeId>,
422    /// Child nodes
423    pub children: Vec<NodeId>,
424    /// First token of this node
425    pub begin_token: TokenId,
426    /// Last token of this node
427    pub end_token: TokenId,
428}
429
430impl JmsSelectorNode {
431    /// Create a new JmsSelector node
432    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
433        JmsSelectorNode {
434            parent: None,
435            children: Vec::new(),
436            begin_token,
437            end_token,
438        }
439    }
440
441}
442
443/// AST node for orExpression production
444#[derive(Debug, Clone)]
445#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
446pub struct OrExpressionNode {
447    /// Parent node (if any)
448    pub parent: Option<NodeId>,
449    /// Child nodes
450    pub children: Vec<NodeId>,
451    /// First token of this node
452    pub begin_token: TokenId,
453    /// Last token of this node
454    pub end_token: TokenId,
455}
456
457impl OrExpressionNode {
458    /// Create a new orExpression node
459    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
460        OrExpressionNode {
461            parent: None,
462            children: Vec::new(),
463            begin_token,
464            end_token,
465        }
466    }
467
468}
469
470/// AST node for andExpression production
471#[derive(Debug, Clone)]
472#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
473pub struct AndExpressionNode {
474    /// Parent node (if any)
475    pub parent: Option<NodeId>,
476    /// Child nodes
477    pub children: Vec<NodeId>,
478    /// First token of this node
479    pub begin_token: TokenId,
480    /// Last token of this node
481    pub end_token: TokenId,
482}
483
484impl AndExpressionNode {
485    /// Create a new andExpression node
486    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
487        AndExpressionNode {
488            parent: None,
489            children: Vec::new(),
490            begin_token,
491            end_token,
492        }
493    }
494
495}
496
497/// AST node for equalityExpression production
498#[derive(Debug, Clone)]
499#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
500pub struct EqualityExpressionNode {
501    /// Parent node (if any)
502    pub parent: Option<NodeId>,
503    /// Child nodes
504    pub children: Vec<NodeId>,
505    /// Operators applied in this expression
506    pub operators: Vec<EqualityOp>,
507    /// First token of this node
508    pub begin_token: TokenId,
509    /// Last token of this node
510    pub end_token: TokenId,
511}
512
513impl EqualityExpressionNode {
514    /// Create a new equalityExpression node
515    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
516        EqualityExpressionNode {
517            parent: None,
518            children: Vec::new(),
519            operators: Vec::new(),
520            begin_token,
521            end_token,
522        }
523    }
524
525}
526
527/// AST node for comparisonExpression production
528#[derive(Debug, Clone)]
529#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
530pub struct ComparisonExpressionNode {
531    /// Parent node (if any)
532    pub parent: Option<NodeId>,
533    /// Child nodes
534    pub children: Vec<NodeId>,
535    /// Operators applied in this expression
536    pub operators: Vec<ComparisonOp>,
537    /// First token of this node
538    pub begin_token: TokenId,
539    /// Last token of this node
540    pub end_token: TokenId,
541}
542
543impl ComparisonExpressionNode {
544    /// Create a new comparisonExpression node
545    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
546        ComparisonExpressionNode {
547            parent: None,
548            children: Vec::new(),
549            operators: Vec::new(),
550            begin_token,
551            end_token,
552        }
553    }
554
555}
556
557/// AST node for addExpression production
558#[derive(Debug, Clone)]
559#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
560pub struct AddExpressionNode {
561    /// Parent node (if any)
562    pub parent: Option<NodeId>,
563    /// Child nodes
564    pub children: Vec<NodeId>,
565    /// Operators between children: operators[i] is between children[i] and children[i+1]
566    pub operators: Vec<AddOp>,
567    /// First token of this node
568    pub begin_token: TokenId,
569    /// Last token of this node
570    pub end_token: TokenId,
571}
572
573impl AddExpressionNode {
574    /// Create a new addExpression node
575    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
576        AddExpressionNode {
577            parent: None,
578            children: Vec::new(),
579            operators: Vec::new(),
580            begin_token,
581            end_token,
582        }
583    }
584
585    /// Get the left operand (first child)
586    pub fn left<'a>(&self, arena: &'a Arena) -> &'a AstNode {
587        arena.get_node(self.children[0])
588    }
589
590    /// Get the right operand (second child for binary case)
591    pub fn right<'a>(&self, arena: &'a Arena) -> Option<&'a AstNode> {
592        self.children.get(1).map(|id| arena.get_node(*id))
593    }
594
595    /// Get operator at index (between children[i] and children[i+1])
596    pub fn op(&self, index: usize) -> Option<AddOp> {
597        self.operators.get(index).copied()
598    }
599
600    /// Get first operator (for binary expressions)
601    pub fn first_op(&self) -> Option<AddOp> {
602        self.operators.first().copied()
603    }
604
605    /// Iterator over (operator, operand) pairs after the first operand
606    pub fn op_operand_pairs(&self) -> impl Iterator<Item = (AddOp, NodeId)> + '_ {
607        self.operators.iter().copied().zip(self.children.iter().skip(1).copied())
608    }
609}
610
611/// AST node for multExpr production
612#[derive(Debug, Clone)]
613#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
614pub struct MultExprNode {
615    /// Parent node (if any)
616    pub parent: Option<NodeId>,
617    /// Child nodes
618    pub children: Vec<NodeId>,
619    /// Operators between children: operators[i] is between children[i] and children[i+1]
620    pub operators: Vec<MultExprOp>,
621    /// First token of this node
622    pub begin_token: TokenId,
623    /// Last token of this node
624    pub end_token: TokenId,
625}
626
627impl MultExprNode {
628    /// Create a new multExpr node
629    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
630        MultExprNode {
631            parent: None,
632            children: Vec::new(),
633            operators: Vec::new(),
634            begin_token,
635            end_token,
636        }
637    }
638
639    /// Get the left operand (first child)
640    pub fn left<'a>(&self, arena: &'a Arena) -> &'a AstNode {
641        arena.get_node(self.children[0])
642    }
643
644    /// Get the right operand (second child for binary case)
645    pub fn right<'a>(&self, arena: &'a Arena) -> Option<&'a AstNode> {
646        self.children.get(1).map(|id| arena.get_node(*id))
647    }
648
649    /// Get operator at index (between children[i] and children[i+1])
650    pub fn op(&self, index: usize) -> Option<MultExprOp> {
651        self.operators.get(index).copied()
652    }
653
654    /// Get first operator (for binary expressions)
655    pub fn first_op(&self) -> Option<MultExprOp> {
656        self.operators.first().copied()
657    }
658
659    /// Iterator over (operator, operand) pairs after the first operand
660    pub fn op_operand_pairs(&self) -> impl Iterator<Item = (MultExprOp, NodeId)> + '_ {
661        self.operators.iter().copied().zip(self.children.iter().skip(1).copied())
662    }
663}
664
665/// AST node for unaryExpr production
666#[derive(Debug, Clone)]
667#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
668pub struct UnaryExprNode {
669    /// Parent node (if any)
670    pub parent: Option<NodeId>,
671    /// Child nodes
672    pub children: Vec<NodeId>,
673    /// Prefix unary operator (if any)
674    pub operator: Option<UnaryOp>,
675    /// First token of this node
676    pub begin_token: TokenId,
677    /// Last token of this node
678    pub end_token: TokenId,
679}
680
681impl UnaryExprNode {
682    /// Create a new unaryExpr node
683    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
684        UnaryExprNode {
685            parent: None,
686            children: Vec::new(),
687            operator: None,
688            begin_token,
689            end_token,
690        }
691    }
692
693}
694
695/// AST node for primaryExpr production
696#[derive(Debug, Clone)]
697#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
698pub struct PrimaryExprNode {
699    /// Parent node (if any)
700    pub parent: Option<NodeId>,
701    /// Child nodes
702    pub children: Vec<NodeId>,
703    /// First token of this node
704    pub begin_token: TokenId,
705    /// Last token of this node
706    pub end_token: TokenId,
707}
708
709impl PrimaryExprNode {
710    /// Create a new primaryExpr node
711    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
712        PrimaryExprNode {
713            parent: None,
714            children: Vec::new(),
715            begin_token,
716            end_token,
717        }
718    }
719
720    /// Get the token image (the actual value as string)
721    pub fn value<'a>(&self, arena: &'a Arena) -> &'a str {
722        &arena.get_token(self.begin_token).image
723    }
724}
725
726/// AST node for literal production
727#[derive(Debug, Clone)]
728#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
729pub struct LiteralNode {
730    /// Parent node (if any)
731    pub parent: Option<NodeId>,
732    /// Child nodes
733    pub children: Vec<NodeId>,
734    /// First token of this node
735    pub begin_token: TokenId,
736    /// Last token of this node
737    pub end_token: TokenId,
738}
739
740impl LiteralNode {
741    /// Create a new literal node
742    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
743        LiteralNode {
744            parent: None,
745            children: Vec::new(),
746            begin_token,
747            end_token,
748        }
749    }
750
751    /// Get the token image (the actual value as string)
752    pub fn value<'a>(&self, arena: &'a Arena) -> &'a str {
753        &arena.get_token(self.begin_token).image
754    }
755}
756
757/// AST node for stringLiteral production
758#[derive(Debug, Clone)]
759#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
760pub struct StringLiteralNode {
761    /// Parent node (if any)
762    pub parent: Option<NodeId>,
763    /// Child nodes
764    pub children: Vec<NodeId>,
765    /// First token of this node
766    pub begin_token: TokenId,
767    /// Last token of this node
768    pub end_token: TokenId,
769}
770
771impl StringLiteralNode {
772    /// Create a new stringLiteral node
773    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
774        StringLiteralNode {
775            parent: None,
776            children: Vec::new(),
777            begin_token,
778            end_token,
779        }
780    }
781
782}
783
784/// AST node for variable production
785#[derive(Debug, Clone)]
786#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
787pub struct VariableNode {
788    /// Parent node (if any)
789    pub parent: Option<NodeId>,
790    /// Child nodes
791    pub children: Vec<NodeId>,
792    /// First token of this node
793    pub begin_token: TokenId,
794    /// Last token of this node
795    pub end_token: TokenId,
796}
797
798impl VariableNode {
799    /// Create a new variable node
800    pub fn new(begin_token: TokenId, end_token: TokenId) -> Self {
801        VariableNode {
802            parent: None,
803            children: Vec::new(),
804            begin_token,
805            end_token,
806        }
807    }
808
809}
810