cfg_grammar/
rule_builder.rs1use std::convert::AsRef;
4
5use crate::local_prelude::*;
6use cfg_history::{
7 LinkedHistoryNode, RootHistoryNode,
8 earley::{History, process_linked},
9};
10
11pub struct RuleBuilder<'a> {
13 lhs: Option<Symbol>,
14 history: Option<History>,
15 grammar: &'a mut Cfg,
16}
17
18impl<'a> RuleBuilder<'a> {
19 pub fn new(grammar: &'a mut Cfg) -> Self {
21 RuleBuilder {
22 lhs: None,
23 history: None,
24 grammar,
25 }
26 }
27}
28
29impl<'a> RuleBuilder<'a> {
30 pub fn rule(mut self, lhs: Symbol) -> Self {
32 self.lhs = Some(lhs);
33 self.history = None;
34 self
35 }
36
37 pub fn history(mut self, history: History) -> Self {
40 self.history = Some(history);
41 self
42 }
43
44 pub fn rhs(mut self, syms: impl AsRef<[Symbol]>) -> Self {
47 let new_history = match self.history.take() {
48 Some(history) => history,
49 None => RootHistoryNode::Rule {
50 lhs: self.lhs.unwrap(),
51 }
52 .into(),
53 };
54 self.rhs_with_history(syms, new_history)
55 }
56
57 pub fn rhs_with_history(self, syms: impl AsRef<[Symbol]>, history: History) -> Self {
59 let lhs = self.lhs.unwrap();
60 let rhs = syms.as_ref().into();
61 self.grammar.add_rule(CfgRule { lhs, rhs, history });
62 self
63 }
64
65 pub fn rhs_with_linked_history(
67 self,
68 syms: impl AsRef<[Symbol]>,
69 linked_history: LinkedHistoryNode,
70 ) -> Self {
71 let history = process_linked(
72 &linked_history,
73 RootHistoryNode::Rule {
74 lhs: self.lhs.unwrap(),
75 }
76 .into(),
77 );
78 self.rhs_with_history(syms, history)
79 }
80
81 pub fn precedenced_rule(self, lhs: Symbol) -> PrecedencedRuleBuilder<'a> {
83 PrecedencedRuleBuilder::new(self.grammar, lhs)
84 }
85}