1use terl::*;
2#[derive(Debug, Clone)]
3pub struct Token {
4 pub string: String,
5 span: Span,
7}
8
9impl Token {
10 pub fn new(string: impl Into<String>, span: Span) -> Self {
11 Self {
12 string: string.into(),
13 span,
14 }
15 }
16}
17
18impl std::ops::Deref for Token {
19 type Target = str;
20
21 fn deref(&self) -> &Self::Target {
22 &self.string
23 }
24}
25
26impl std::fmt::Display for Token {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 self.string.fmt(f)
29 }
30}
31
32impl WithSpan for Token {
33 #[inline]
34 fn get_span(&self) -> Span {
35 self.span
36 }
37}
38
39impl ParseUnit<char> for Token {
40 type Target = Self;
41
42 fn parse(p: &mut Parser<char>) -> ParseResult<Self, char> {
43 fn w(c: &char) -> bool {
44 c.is_ascii_alphanumeric() || *c == '_'
45 }
46
47 while p.next_if(|c| !w(c)).is_some() {}
49
50 let mut string = String::new();
52 p.start_taking();
53 while let Some(next) = p.next_if(w) {
54 string.push(*next);
55 }
56
57 if string.is_empty() {
59 return p.unmatch("empty string");
60 }
61
62 Ok(Token {
63 string,
64 span: p.get_span(),
65 })
66 }
67}
68
69impl ParseUnit<Token> for Token {
70 type Target = Token;
71
72 #[inline]
73 fn parse(p: &mut Parser<Token>) -> Result<Self::Target, ParseError> {
74 match p.next().cloned() {
75 Some(token) => Ok(token),
76 None => p.unmatch("no token left"),
77 }
78 }
79}
80
81impl Source for Token {
82 type HandleErrorWith<'b> = (&'b Buffer<char>, &'b Buffer<Token>);
83
84 #[inline]
85 fn handle_location<S>(
86 with: &Self::HandleErrorWith<'_>,
87 buffer: &mut S,
88 loc: Span,
89 msg: &str,
90 ) -> std::fmt::Result
91 where
92 S: std::fmt::Write,
93 {
94 let (chars, tokens) = with;
95 let loc = tokens[loc.start].get_span() + tokens[loc.end - 1].get_span();
96 char::handle_location(chars, buffer, loc, msg)
97 }
98}
99
100pub struct PU<P> {
102 pub(crate) span: Span,
103 pub(crate) item: P,
104}
105
106impl<S, P> ParseUnit<S> for PU<P>
107where
108 P: ParseUnit<S>,
109 S: Source,
110{
111 type Target = PU<P::Target>;
112
113 fn parse(p: &mut Parser<S>) -> Result<Self::Target, ParseError> {
114 P::parse(p).map(|item| PU::new(p.get_span(), item))
115 }
116}
117
118impl<P> WithSpan for PU<P> {
119 fn get_span(&self) -> Span {
120 self.span
121 }
122}
123
124impl<P> PU<P> {
125 #[inline]
126 pub const fn new(span: Span, item: P) -> Self {
127 Self { span, item }
128 }
129
130 #[inline]
132 pub fn take(self) -> P {
133 self.item
134 }
135
136 #[inline]
138 pub fn map<P1, M>(self, mapper: M) -> PU<P1>
139 where
140 M: FnOnce(P) -> P1,
141 {
142 PU::new(self.span, mapper(self.item))
143 }
144}
145
146impl<P> std::fmt::Debug for PU<P>
147where
148 P: std::fmt::Debug,
149{
150 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
151 f.debug_struct("PU")
152 .field("span", &self.span)
153 .field("item", &self.item)
154 .finish()
155 }
156}
157
158impl<P> std::fmt::Display for PU<P>
159where
160 P: std::fmt::Display,
161{
162 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
163 std::fmt::Display::fmt(&self.item, f)
164 }
165}
166
167impl<P> Clone for PU<P>
168where
169 P: Clone,
170{
171 fn clone(&self) -> Self {
172 Self {
173 span: self.span,
174 item: self.item.clone(),
175 }
176 }
177}
178
179impl<P> Copy for PU<P> where P: Copy {}
180
181impl<P> std::ops::Deref for PU<P> {
182 type Target = P;
183
184 fn deref(&self) -> &Self::Target {
185 &self.item
186 }
187}
188
189impl<P> std::ops::DerefMut for PU<P> {
190 fn deref_mut(&mut self) -> &mut Self::Target {
191 &mut self.item
192 }
193}
194
195pub struct RPU<Item>(pub Item);
196
197impl<Item, S: Source> ReverseParseUnit<S> for RPU<Item>
198where
199 Item: ReverseParseUnit<S>,
200{
201 type Left = PU<Item::Left>;
202
203 #[inline]
204 fn reverse_parse(&self, p: &mut Parser<S>) -> Result<Self::Left, ParseError> {
205 self.0
206 .reverse_parse(p)
207 .map(|item| PU::new(p.get_span(), item))
208 }
209}
210
211#[cfg(test)]
212mod tests {
213
214 use super::*;
215
216 #[test]
217
218 fn token() {
219 use terl::*;
220 let file_name = std::any::type_name_of_val(&token).to_owned();
221 let src = "123456 abcde \n 114514abc [] ()";
222 let buffer = Buffer::new(file_name, src.chars().collect());
223 let mut parser = Parser::new(buffer);
224
225 let mut tokens: Vec<_> = vec![];
226 while let Some(token) = parser.parse::<PU<Token>>().apply(mapper::Try).unwrap() {
227 tokens.push(token)
228 }
229
230 let expect = src.chars().enumerate().collect::<Vec<_>>();
231 let expect = expect
232 .split(|(.., c)| c.is_whitespace())
233 .fold(vec![], |mut expect, slice| {
234 if !slice.is_empty() {
236 let span = Span::new(slice.first().unwrap().0, slice.last().unwrap().0);
237 let string = slice.iter().map(|(.., c)| c).collect::<String>();
238 expect.push(Token::new(string, span));
239 }
240 expect
241 });
242
243 for (got, expect) in tokens.into_iter().zip(expect) {
244 let (got, expect): (&str, &str) = (&got, &expect);
245 assert_eq!(got, expect);
246 }
247 }
248}