1use crate::grammar::GrammarRule;
7use sipha_core::traits::{RuleId, TokenKind};
8
9pub fn token<K: TokenKind, R: RuleId>(token: K) -> GrammarRule<K, R> {
11 GrammarRule::Token(token)
12}
13
14pub fn rule<K: TokenKind, R: RuleId>(rule: R) -> GrammarRule<K, R> {
16 GrammarRule::Rule(rule)
17}
18
19pub fn choice<K: TokenKind, R: RuleId>(alternatives: Vec<GrammarRule<K, R>>) -> GrammarRule<K, R> {
23 GrammarRule::Choice(alternatives)
24}
25
26pub fn seq<K: TokenKind, R: RuleId>(rules: Vec<GrammarRule<K, R>>) -> GrammarRule<K, R> {
30 GrammarRule::Sequence(rules)
31}
32
33pub fn opt<K: TokenKind, R: RuleId>(rule: GrammarRule<K, R>) -> GrammarRule<K, R> {
35 GrammarRule::Optional(Box::new(rule))
36}
37
38pub fn many<K: TokenKind, R: RuleId>(rule: GrammarRule<K, R>) -> GrammarRule<K, R> {
40 GrammarRule::ZeroOrMore(Box::new(rule))
41}
42
43pub fn many1<K: TokenKind, R: RuleId>(rule: GrammarRule<K, R>) -> GrammarRule<K, R> {
45 GrammarRule::OneOrMore(Box::new(rule))
46}
47
48pub fn delimited<K: TokenKind, R: RuleId>(
52 open: K,
53 content: GrammarRule<K, R>,
54 close: K,
55) -> GrammarRule<K, R> {
56 seq(vec![token(open), content, token(close)])
57}
58
59pub fn separated_list<K: TokenKind, R: RuleId>(
63 item: GrammarRule<K, R>,
64 separator: K,
65) -> GrammarRule<K, R> {
66 seq(vec![
67 item.clone(),
68 many(seq(vec![token(separator), item])),
69 ])
70}
71
72pub fn terminated<K: TokenKind, R: RuleId>(
76 item: GrammarRule<K, R>,
77 terminator: K,
78) -> GrammarRule<K, R> {
79 seq(vec![item, token(terminator)])
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
87 enum TestToken {
88 A,
89 }
90
91 impl TokenKind for TestToken {
92 fn is_trivia(&self) -> bool {
93 false
94 }
95 }
96
97 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
98 enum TestRule {
99 Expr,
100 }
101
102 #[test]
103 fn test_helper_functions() {
104 let _token_rule: GrammarRule<TestToken, TestRule> = token(TestToken::A);
105 let _rule_ref: GrammarRule<TestToken, TestRule> = rule(TestRule::Expr);
106 let _choice_rule: GrammarRule<TestToken, TestRule> = choice(vec![token(TestToken::A)]);
107 let _seq_rule: GrammarRule<TestToken, TestRule> = seq(vec![token(TestToken::A)]);
108 let _opt_rule: GrammarRule<TestToken, TestRule> = opt(token(TestToken::A));
109 let _many_rule: GrammarRule<TestToken, TestRule> = many(token(TestToken::A));
110 let _many1_rule: GrammarRule<TestToken, TestRule> = many1(token(TestToken::A));
111 }
112}