1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Grammar rules can be built with the builder pattern.

use std::convert::AsRef;

use crate::history::{HistoryNodeRhs, LinkedHistoryNode, RootHistoryNode};
use crate::precedence::PrecedencedRuleBuilder;
use crate::prelude::*;

/// The rule builder.
pub struct RuleBuilder<C>
where
    C: RuleContainer,
{
    lhs: Option<Symbol>,
    history: Option<HistoryId>,
    rules: C,
}

impl<C> RuleBuilder<C>
where
    C: RuleContainer,
{
    /// Creates a rule builder.
    pub fn new(rules: C) -> RuleBuilder<C> {
        RuleBuilder {
            lhs: None,
            history: None,
            rules: rules,
        }
    }
}

impl<C> RuleBuilder<C>
where
    C: RuleContainer,
{
    /// Starts building a new rule with the given LHS.
    pub fn rule(mut self, lhs: Symbol) -> Self {
        self.lhs = Some(lhs);
        self.history = None;
        self
    }

    /// Assigns the rule history, which is used on the next call to `rhs`, or overwritten by a call
    /// to `rhs_with_history`.
    pub fn history(mut self, history: HistoryId) -> Self {
        self.history = Some(history);
        self
    }

    /// Adds a rule alternative to the grammar. If history wasn't provided, the rule has the
    /// `Default` history.
    pub fn rhs<S>(mut self, syms: S) -> Self
    where
        S: AsRef<[Symbol]>,
    {
        let new_history = match self.history.take() {
            Some(history) => self.rules.add_history_node(
                HistoryNodeRhs {
                    prev: history,
                    rhs: syms.as_ref().to_vec(),
                }
                .into(),
            ),
            None => {
                let base_id = self.rules.add_history_node(
                    RootHistoryNode::Rule {
                        lhs: self.lhs.unwrap(),
                    }
                    .into(),
                );
                self.rules.add_history_node(
                    HistoryNodeRhs {
                        prev: base_id,
                        rhs: syms.as_ref().to_vec(),
                    }
                    .into(),
                )
            }
        };
        self.rhs_with_history(syms, new_history)
    }

    /// Adds a rule alternative with the given RHS and history to the grammar.
    pub fn rhs_with_history<Sr>(mut self, syms: Sr, history_id: HistoryId) -> Self
    where
        Sr: AsRef<[Symbol]>,
    {
        self.rules
            .add_rule(self.lhs.unwrap(), syms.as_ref(), history_id);
        self
    }

    /// Adds a rule alternative with the given RHS and history to the grammar.
    pub fn rhs_with_linked_history<Sr>(
        mut self,
        syms: Sr,
        linked_history: LinkedHistoryNode,
    ) -> Self
    where
        Sr: AsRef<[Symbol]>,
    {
        let base_id = self.rules.add_history_node(
            RootHistoryNode::Rule {
                lhs: self.lhs.unwrap(),
            }
            .into(),
        );
        let new_history = self.rules.add_history_node(
            HistoryNodeRhs {
                prev: base_id,
                rhs: syms.as_ref().to_vec(),
            }
            .into(),
        );
        let history_id = self.rules.add_history_node(HistoryNode::Linked {
            prev: new_history,
            node: linked_history,
        });
        self.rules
            .add_rule(self.lhs.unwrap(), syms.as_ref(), history_id);
        self
    }

    /// Starts building a new precedenced rule.
    pub fn precedenced_rule(self, lhs: Symbol) -> PrecedencedRuleBuilder<C> {
        PrecedencedRuleBuilder::new(self.rules, lhs)
    }
}