syntax_parser_generator/parsing/lr_parser/
rules.rs

1use derive_where::derive_where;
2
3use crate::handles::{Handle, Handled};
4use crate::handles::specials::OrderlyHandled;
5
6#[derive_where(Debug)]
7pub struct ProductionRule<Terminal, Nonterminal, Tag>
8where
9    Terminal: Handled,
10    Nonterminal: Handled,
11    Tag: Handled,
12{
13    pub(super) lhs: Handle<Nonterminal>,
14    pub(super) rhs: Vec<GrammarSymbol<Terminal, Nonterminal>>,
15    pub(super) tag: Handle<Tag>,
16    pub(super) binding: Option<Handle<Binding<Terminal>>>,
17}
18
19impl<Terminal, Nonterminal, Tag> ProductionRule<Terminal, Nonterminal, Tag>
20where
21    Terminal: Handled,
22    Nonterminal: Handled,
23    Tag: Handled,
24{
25    pub fn new(
26        lhs: Handle<Nonterminal>,
27        rhs: Vec<GrammarSymbol<Terminal, Nonterminal>>,
28        tag: Handle<Tag>,
29        binding: Option<Handle<Binding<Terminal>>>,
30    ) -> Self {
31        Self {
32            lhs,
33            rhs,
34            tag,
35            binding,
36        }
37    }
38}
39
40impl<Terminal, Nonterminal, Tag> Handled for ProductionRule<Terminal, Nonterminal, Tag>
41where
42    Terminal: Handled,
43    Nonterminal: Handled,
44    Tag: Handled,
45{
46    type HandleCoreType = Tag::HandleCoreType;
47}
48
49#[derive_where(Debug, Clone, Copy)]
50pub enum GrammarSymbol<Terminal: Handled, Nonterminal: Handled> {
51    Terminal(Handle<Terminal>),
52    Nonterminal(Handle<Nonterminal>),
53}
54
55impl<Terminal: Handled, Nonterminal: Handled> Handled for GrammarSymbol<Terminal, Nonterminal> {
56    type HandleCoreType = u16;
57}
58
59/// Represents the associativity of a binding of a grammar's terminals and production rules.
60///
61/// See [syntaxDirectedTranslatorBuilder](crate::parsing::SyntaxDirectedTranslatorBuilder) for more
62/// details.
63pub enum Associativity {
64    /// Represents left-associated binding.
65    ///
66    /// For example - the addition operator's binding is left-associated.
67    Left,
68
69    /// Represents right-associated binding.
70    ///
71    /// For example - the unary minus operator's binding is right-associated.
72    Right,
73
74    /// Represents bindings that cannot be associated to either left or right.
75    None,
76}
77
78pub struct Binding<Terminal: Handled> {
79    pub(super) terminals: Vec<Handle<Terminal>>,
80    pub(super) associativity: Associativity,
81}
82
83impl<Terminal> Binding<Terminal>
84where
85    Terminal: Handled,
86{
87    pub fn new(terminals: Vec<Handle<Terminal>>, associativity: Associativity) -> Self {
88        Self {
89            terminals,
90            associativity,
91        }
92    }
93}
94
95impl<Terminal: Handled> Handled for Binding<Terminal> {
96    type HandleCoreType = u8;
97}
98impl<Terminal: Handled> OrderlyHandled for Binding<Terminal> {}