forester_rs/tree/
parser.rs

1pub mod ast;
2mod lexer;
3mod tests;
4
5use crate::tree::parser::ast::*;
6use crate::tree::parser::lexer::Token;
7use crate::tree::TreeError;
8use ast::arg::{Argument, ArgumentRhs, Arguments, MesType, Param, Params};
9use ast::call::{Call, Calls};
10use ast::message::{Bool, Message, Number, StringLit};
11use parsit::error::ParseError;
12use parsit::parser::{EmptyToken, Parsit};
13use parsit::step::Step;
14use parsit::{seq, token, wrap};
15use std::collections::HashMap;
16use std::str::FromStr;
17
18/// just a parser for the tree language
19///
20/// # Example of the language
21/// ```tree
22/// // built in library        
23/// import "std:actions"
24///
25/// r_fallback retry_with_delay(delay:num, attempts:num,trg:tree){
26///     retry(attempts) fallback {
27///         trg(..)
28///         wait(delay)
29///         fail()
30///     }
31///     wait(delay)
32/// }
33/// ```
34
35pub struct Parser<'a> {
36    inner: Parsit<'a, Token>,
37}
38
39impl<'a> Parser<'a> {
40    fn assign(&self, pos: usize) -> Step<'a, EmptyToken> {
41        token!(self.token(pos) => Token::Assign )
42    }
43    fn semi(&self, pos: usize) -> Step<'a, EmptyToken> {
44        token!(self.token(pos) => Token::Semi )
45    }
46    fn l_pr(&self, pos: usize) -> Step<'a, EmptyToken> {
47        token!(self.token(pos) => Token::LParen )
48    }
49    fn dot_dot(&self, pos: usize) -> Step<'a, EmptyToken> {
50        token!(self.token(pos) => Token::DotDot )
51    }
52    fn a_arr(&self, pos: usize) -> Step<'a, EmptyToken> {
53        token!(self.token(pos) => Token::AssignArr )
54    }
55    fn r_pr(&self, pos: usize) -> Step<'a, EmptyToken> {
56        token!(self.token(pos) => Token::RParen )
57    }
58    fn l_brc(&self, pos: usize) -> Step<'a, EmptyToken> {
59        token!(self.token(pos) => Token::LBrace )
60    }
61    fn r_brc(&self, pos: usize) -> Step<'a, EmptyToken> {
62        token!(self.token(pos) => Token::RBrace )
63    }
64    fn l_br(&self, pos: usize) -> Step<'a, EmptyToken> {
65        token!(self.token(pos) => Token::LBrack )
66    }
67    fn r_br(&self, pos: usize) -> Step<'a, EmptyToken> {
68        token!(self.token(pos) => Token::RBrack )
69    }
70
71    fn comma(&self, pos: usize) -> Step<'a, EmptyToken> {
72        token!(self.token(pos) => Token::Comma )
73    }
74    fn colon(&self, pos: usize) -> Step<'a, EmptyToken> {
75        token!(self.token(pos) => Token::Colon )
76    }
77    fn import_tk(&self, pos: usize) -> Step<'a, EmptyToken> {
78        token!(self.token(pos) => Token::Import )
79    }
80
81    fn id(&self, pos: usize) -> Step<'a, Key> {
82        token!(self.token(pos) => Token::Id(v) => v.clone() )
83    }
84    fn str(&self, pos: usize) -> Step<'a, StringLit> {
85        token!(self.token(pos) => Token::StringLit(v) => StringLit(v.clone()) )
86    }
87    fn num(&self, pos: usize) -> Step<'a, Number> {
88        token!(self.token(pos) => Token::Digit(n) => *n )
89    }
90    fn bool(&self, pos: usize) -> Step<'a, Bool> {
91        token!(self.token(pos) =>
92                Token::True => Bool::True ,
93                Token::False => Bool::False
94        )
95    }
96
97    fn array(&'a self, pos: usize) -> Step<'a, Vec<Message>> {
98        let l = |p| self.l_br(p);
99        let r = |p| self.r_br(p);
100        let comma = |p| self.comma(p);
101        let message = |p| self.message(p);
102        let elems = |p| seq!(p => message, comma,);
103        let no_elems = vec![];
104
105        wrap!(pos => l; elems or no_elems; r)
106    }
107    fn object(&'a self, pos: usize) -> Step<'a, HashMap<String, Message>> {
108        let l = |p| self.l_brc(p);
109        let r = |p| self.r_brc(p);
110        let comma = |p| self.comma(p);
111
112        let pair = |p| {
113            self.str(p)
114                .map(|l| l.0)
115                .then_skip(|p| self.colon(p))
116                .then_zip(|p| self.message(p))
117        };
118
119        let elems = |p| seq!(p => pair, comma,).map(HashMap::from_iter);
120
121        let def = HashMap::new();
122
123        wrap!(pos => l; elems or def; r)
124    }
125    fn params(&self, pos: usize) -> Step<'a, Params> {
126        let l = |p| self.l_pr(p);
127        let r = |p| self.r_pr(p);
128        let comma = |p| self.comma(p);
129
130        let param = |p| {
131            self.id(p)
132                .then_skip(|p| self.colon(p))
133                .then_zip(|p| self.mes_type(p))
134                .map(|(name, tpe)| Param { name, tpe })
135        };
136
137        let elems = |p| seq!(p => param, comma,).map(|params| Params { params });
138        let def = Params { params: vec![] };
139
140        wrap!(pos => l; elems or def; r)
141    }
142
143    fn arg(&'a self, pos: usize) -> Step<'a, Argument> {
144        let assign = |p| self.assign(p);
145        let assigned = |p| self.id(p).then_skip(assign);
146
147        let assign_id = |p| {
148            assigned(p)
149                .then_zip(|p| self.id(p).map(ArgumentRhs::Id))
150                .map(|(a, b)| Argument::Assigned(a, b))
151        };
152
153        let assign_mes = |p| {
154            assigned(p)
155                .then_zip(|p| self.message(p).map(ArgumentRhs::Mes))
156                .map(|(a, b)| Argument::Assigned(a, b))
157        };
158        let assign_call = |p| {
159            assigned(p)
160                .then_zip(|p| self.call(p).map(ArgumentRhs::Call))
161                .map(|(a, b)| Argument::Assigned(a, b))
162        };
163
164        let mes = |p| {
165            self.message(p)
166                .map(ArgumentRhs::Mes)
167                .map(Argument::Unassigned)
168        };
169        let id = |p| self.id(p).map(ArgumentRhs::Id).map(Argument::Unassigned);
170        let call = |p| {
171            self.call(p)
172                .map(ArgumentRhs::Call)
173                .map(Argument::Unassigned)
174        };
175
176        assign_mes(pos)
177            .or_from(pos)
178            .or(assign_call)
179            .or(assign_id)
180            .or(call)
181            .or(mes)
182            .or(id)
183            .into()
184    }
185
186    fn args(&'a self, pos: usize) -> Step<'a, Arguments> {
187        let l = |p| self.l_pr(p);
188        let r = |p| self.r_pr(p);
189        let comma = |p| self.comma(p);
190
191        let arg = |p| self.arg(p);
192
193        let elems = |p| seq!(p => arg, comma,).map(|args| Arguments { args });
194
195        let def = Arguments { args: vec![] };
196
197        wrap!(pos => l; elems or def; r)
198    }
199    fn tree_type(&self, pos: usize) -> Step<'a, TreeType> {
200        self.id(pos)
201            .flat_map(|p| TreeType::from_str(&p), |_pe| Step::Fail(pos))
202    }
203
204    fn mes_type(&self, pos: usize) -> Step<'a, MesType> {
205        token!(self.token(pos) =>
206                Token::StringT => MesType::String ,
207                Token::NumT => MesType::Num,
208                Token::ArrayT => MesType::Array,
209                Token::BoolT => MesType::Bool,
210                Token::TreeT => MesType::Tree,
211                Token::ObjectT => MesType::Object,
212                Token::AnyT => MesType::Any
213        )
214    }
215
216    fn message(&'a self, pos: usize) -> Step<'a, Message> {
217        self.str(pos)
218            .map(Message::String)
219            .or_from(pos)
220            .or(|p| self.num(p).map(Message::Num))
221            .or(|p| self.bool(p).map(Message::Bool))
222            .or(|p| self.array(p).map(Message::Array))
223            .or(|p| self.object(p).map(Message::Object))
224            .into()
225    }
226
227    fn call_partial(&'a self, pos: usize) -> Step<'a, Key> {
228        self.id(pos)
229            .then_skip(|p| self.l_pr(p))
230            .then_skip(|p| self.dot_dot(p))
231            .then_skip(|p| self.r_pr(p))
232    }
233
234    fn call(&'a self, pos: usize) -> Step<'a, Call> {
235        let inv = |p| {
236            self.id(p)
237                .then_zip(|p| self.args(p))
238                .map(|(id, args)| Call::Invocation(id, args))
239                .or_from(p)
240                .or(|p| self.call_partial(p).map(Call::HoInvocation))
241                .into()
242        };
243
244        let anon = |p| {
245            self.tree_type(p)
246                .then_or_default_zip(|p| self.args(p))
247                .then_zip(|p| self.calls(p))
248                .validate(|((t, args), calls)| validate_lambda(t, args, calls))
249                .map(|((t, args), calls)| {
250                    if t.is_decorator() {
251                        Call::decorator(t, args, calls.elems[0].clone())
252                    } else {
253                        Call::lambda(t, calls)
254                    }
255                })
256        };
257
258        anon(pos).or_from(pos).or(inv).into()
259    }
260    fn calls(&'a self, pos: usize) -> Step<'a, Calls> {
261        let calls = |p| {
262            let l = |p| self.l_brc(p);
263            let r = |p| self.r_brc(p);
264            let calls = |p| self.inner.zero_or_more(p, |p| self.call(p));
265            wrap!(p => l;calls;r).map(Calls::new)
266        };
267
268        calls(pos)
269            .or_from(pos)
270            .or(|p| self.call(p).map(|c| Calls { elems: vec![c] }))
271            .into()
272    }
273
274    fn tree(&'a self, pos: usize) -> Step<'a, Tree> {
275        self.tree_type(pos)
276            .then_zip(|p| self.id(p))
277            .then_or_default_zip(|p| self.params(p))
278            .then_or_default_zip(|p| self.semi(p).map(|_| Calls::default()).or(|p| self.calls(p)))
279            .map(|(((tpe, name), params), calls)| Tree {
280                tpe,
281                name,
282                params,
283                calls,
284            })
285    }
286
287    fn import(&'a self, pos: usize) -> Step<'a, Import> {
288        let l = |p| self.l_brc(p);
289        let r = |p| self.r_brc(p);
290        let comma = |p| self.comma(p);
291        let name = |p| {
292            self.id(p)
293                .then_or_none_zip(|p| self.a_arr(p).then(|p| self.id(p)).or_none())
294                .map(|(id, alias)| match alias {
295                    None => ImportName::Id(id),
296                    Some(a) => ImportName::Alias(id, a),
297                })
298        };
299        let names = |p| seq!(p => name, comma,);
300
301        let part = |p| {
302            let def = vec![];
303            wrap!(p => l;names or def; r ).or_none()
304        };
305
306        self.import_tk(pos)
307            .then_zip(|p| self.str(p))
308            .take_right()
309            .then_or_none_zip(part)
310            .map(|(file, parts)| match parts {
311                None => Import::file(file.0.as_str()),
312                Some(names) => Import(file.0, names),
313            })
314    }
315
316    fn file(&'a self, pos: usize) -> Step<'a, AstFile> {
317        let entity = |p| {
318            let entity: Step<FileEntity> = self
319                .tree(p)
320                .map(FileEntity::Tree)
321                .or_from(p)
322                .or(|p| self.import(p).map(FileEntity::Import))
323                .into();
324            entity
325        };
326
327        self.inner.zero_or_more(pos, entity).map(AstFile::new)
328    }
329}
330
331impl<'a> Parser<'a> {
332    pub fn new(src: &'a str) -> Result<Self, TreeError> {
333        Ok(Parser {
334            inner: Parsit::new(src)?,
335        })
336    }
337
338    fn token(&self, pos: usize) -> Result<(&Token, usize), ParseError<'a>> {
339        self.inner.token(pos)
340    }
341
342    pub fn parse(&'a self) -> Result<AstFile, TreeError> {
343        let step: Step<AstFile> = self.inner.validate_eof(self.file(0));
344
345        match step.clone() {
346            Step::Success(file, _pos) => Ok(file),
347            Step::Fail(pos) => {
348                let env = self.inner.env(&step);
349                Err(TreeError::ParseError(format!(
350                    "Parse error on the position: {pos} with the env: `{env}`"
351                )))
352            }
353            Step::Error(ParseError::BadToken(t, _)) => {
354                let env = self.inner.env(&step);
355                Err(TreeError::ParseError(format!(
356                    "Parse error the token: `{t}` is not recognized with the env: `{env}`"
357                )))
358            }
359            Step::Error(ParseError::ExternalError(ext_t, pos)) => {
360                let env = self.inner.env(&step);
361                Err(TreeError::ParseError(format!(
362                    "Parse error the token: `{ext_t}` on the pos:`{pos}` is not recognized with the env: `{env}`"
363                )))
364            }
365            Step::Error(ParseError::FailedOnValidation(ext_t, pos)) => {
366                let env = self.inner.env(&step);
367                Err(TreeError::ParseError(format!(
368                    "Parse error on the validation `{ext_t}` on the pos:`{pos}` is not recognized with the env: `{env}`"
369                )))
370            }
371            Step::Error(ParseError::ReachedEOF(pos)) => {
372                let env = self.inner.env(&step);
373                Err(TreeError::ParseError(format!(
374                    "Parse error on the pos:`{pos}` is reached eof with the env: `{env}`"
375                )))
376            }
377            Step::Error(ParseError::UnreachedEOF(pos)) => {
378                let env = self.inner.env(&step);
379                Err(TreeError::ParseError(format!(
380                    "Parse error on the pos:`{pos}` is unreached eof with the env: `{env}`"
381                )))
382            }
383            Step::Error(err) => Err(TreeError::ParseError(err.to_string())),
384        }
385    }
386}