harper_core/expr/
sequence_expr.rs1use paste::paste;
2
3use crate::{
4 Span, Token, TokenKind,
5 patterns::{AnyPattern, IndefiniteArticle, WhitespacePattern, Word},
6};
7
8use super::{Expr, Optional, Repeating, Step, UnlessStep};
9
10#[derive(Default)]
11pub struct SequenceExpr {
12 exprs: Vec<Box<dyn Expr>>,
13}
14
15macro_rules! gen_then_from_is {
17 ($quality:ident) => {
18 paste! {
19 pub fn [< then_$quality >] (self) -> Self{
20 self.then(|tok: &Token, _source: &[char]| {
21 tok.kind.[< is_$quality >]()
22 })
23 }
24
25 pub fn [< then_one_or_more_$quality s >] (self) -> Self{
26 self.then_one_or_more(Box::new(|tok: &Token, _source: &[char]| {
27 tok.kind.[< is_$quality >]()
28 }))
29 }
30
31 pub fn [< then_anything_but_$quality >] (self) -> Self{
32 self.then(|tok: &Token, _source: &[char]| {
33 if tok.kind.[< is_$quality >](){
34 false
35 }else{
36 true
37 }
38 })
39 }
40 }
41 };
42}
43
44impl Expr for SequenceExpr {
45 fn run(&self, mut cursor: usize, tokens: &[Token], source: &[char]) -> Option<Span> {
49 let mut window = Span::new_with_len(cursor, 0);
50
51 for cur_expr in &self.exprs {
52 let out = cur_expr.run(cursor, tokens, source)?;
53
54 if out.end > out.start {
56 window.expand_to_include(out.start);
57 window.expand_to_include(out.end.checked_sub(1).unwrap_or(out.start));
58 }
59
60 if out.end > cursor {
62 cursor = out.end;
63 } else if out.start < cursor {
64 cursor = out.start;
65 }
66 }
68
69 Some(window)
70 }
71}
72
73impl SequenceExpr {
74 pub fn then(mut self, expr: impl Expr + 'static) -> Self {
75 self.exprs.push(Box::new(expr));
76 self
77 }
78
79 pub fn then_optional(mut self, expr: impl Expr + 'static) -> Self {
81 self.exprs.push(Box::new(Optional::new(expr)));
82 self
83 }
84
85 pub fn then_expr(mut self, mut other: Self) -> Self {
87 self.exprs.append(&mut other.exprs);
88 self
89 }
90
91 pub fn then_indefinite_article(self) -> Self {
92 self.then(IndefiniteArticle::default())
93 }
94
95 pub fn then_exact_word(self, word: &'static str) -> Self {
97 self.then(Word::new_exact(word))
98 }
99
100 pub fn aco(word: &'static str) -> Self {
102 Self::any_capitalization_of(word)
103 }
104
105 pub fn any_capitalization_of(word: &'static str) -> Self {
106 Self::default().then_any_capitalization_of(word)
107 }
108
109 pub fn t_aco(self, word: &'static str) -> Self {
111 self.then_any_capitalization_of(word)
112 }
113
114 pub fn then_any_capitalization_of(self, word: &'static str) -> Self {
116 self.then(Word::new(word))
117 }
118
119 pub fn then_any_word(self) -> Self {
121 self.then(|tok: &Token, _source: &[char]| tok.kind.is_word())
122 }
123
124 pub fn then_strict(self, kind: TokenKind) -> Self {
126 self.then(move |tok: &Token, _source: &[char]| tok.kind == kind)
127 }
128
129 pub fn t_ws(self) -> Self {
131 self.then_whitespace()
132 }
133
134 pub fn then_whitespace(self) -> Self {
136 self.then(WhitespacePattern)
137 }
138
139 pub fn then_one_or_more(self, expr: impl Expr + 'static) -> Self {
140 self.then(Repeating::new(Box::new(expr), 1))
141 }
142
143 pub fn if_not_then_step_one(self, condition: impl Expr + 'static) -> Self {
145 self.then(UnlessStep::new(condition, |_tok: &Token, _src: &[char]| {
146 true
147 }))
148 }
149
150 pub fn t_any(self) -> Self {
151 self.then_anything()
152 }
153
154 pub fn then_anything(self) -> Self {
155 self.then(AnyPattern)
156 }
157
158 gen_then_from_is!(nominal);
159 gen_then_from_is!(noun);
160 gen_then_from_is!(possessive_nominal);
161 gen_then_from_is!(plural_nominal);
162 gen_then_from_is!(verb);
163 gen_then_from_is!(auxiliary_verb);
164 gen_then_from_is!(linking_verb);
165 gen_then_from_is!(pronoun);
166 gen_then_from_is!(punctuation);
167 gen_then_from_is!(conjunction);
168 gen_then_from_is!(comma);
169 gen_then_from_is!(period);
170 gen_then_from_is!(number);
171 gen_then_from_is!(case_separator);
172 gen_then_from_is!(adverb);
173 gen_then_from_is!(adjective);
174 gen_then_from_is!(apostrophe);
175 gen_then_from_is!(hyphen);
176 gen_then_from_is!(determiner);
177 gen_then_from_is!(proper_noun);
178 gen_then_from_is!(preposition);
179 gen_then_from_is!(third_person_pronoun);
180 gen_then_from_is!(third_person_singular_pronoun);
181 gen_then_from_is!(third_person_plural_pronoun);
182 gen_then_from_is!(first_person_singular_pronoun);
183 gen_then_from_is!(first_person_plural_pronoun);
184 gen_then_from_is!(second_person_pronoun);
185 gen_then_from_is!(non_plural_nominal);
186}
187
188impl<S> From<S> for SequenceExpr
189where
190 S: Step + 'static,
191{
192 fn from(step: S) -> Self {
193 Self {
194 exprs: vec![Box::new(step)],
195 }
196 }
197}