Skip to main content

unlab_gpu/
parser.rs

1//
2// Copyright (c) 2025-2026 Ɓukasz Szpakowski
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7//
8//! A parser module.
9use std::fs::File;
10use std::io::BufReader;
11use std::path::Path;
12use std::sync::Arc;
13use std::sync::RwLock;
14use crate::doc::*;
15use crate::error::*;
16use crate::lexer::*;
17use crate::mod_node::*;
18use crate::tree::*;
19use crate::utils::*;
20
21#[derive(Clone, Debug)]
22enum FillableExprs
23{
24    Exprs(Vec<Box<Expr>>),
25    FilledExprs(Box<Expr>, Box<Expr>),
26}
27
28#[derive(Clone, Debug)]
29struct DocEnv
30{
31    root_mod: Arc<RwLock<ModNode<String, Option<String>>>>,
32    current_mod: Arc<RwLock<ModNode<String, Option<String>>>>,
33}
34
35impl DocEnv
36{
37    fn new(root_mod: Arc<RwLock<ModNode<String, Option<String>>>>, current_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>) -> Self
38    { DocEnv { root_mod: root_mod.clone(), current_mod: current_mod.unwrap_or(root_mod), } }
39}
40
41/// A parser structure.
42///
43/// The parser parses tokens to a syntax tree that can be interpreted by an interpreter. The
44/// tokens are passed as an iterator that can be a lexer. Also, the parser can take the
45/// documentation comments from the lexer and then stores this comments as the documentation of
46/// modules and variables.
47pub struct Parser<'a>
48{
49    path: Arc<String>,
50    tokens: PushbackIter<&'a mut dyn DocIterator<Item = Result<(Token, Pos)>>>,
51    doc_env: Option<DocEnv>,
52}
53
54impl<'a> Parser<'a>
55{
56    /// Creates a parser with the root module of documentation and the current module of
57    /// documentation.
58    ///
59    /// Also, this method takes the path that refers to the script and the tokens as the iterator.
60    /// The parser stores the documentation if the root module of documentation is passed. If the 
61    /// current module of documentation is passed, the parser stores the documentation in this
62    /// module instead of the root module of documentation.
63    pub fn new_with_doc_root_mod_and_doc_current_mod(path: Arc<String>, tokens: &'a mut dyn DocIterator<Item = Result<(Token, Pos)>>, doc_root_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>, doc_current_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>) -> Self
64    {
65        let doc_env = match doc_root_mod {
66            Some(doc_root_mod) => Some(DocEnv::new(doc_root_mod, doc_current_mod)),
67            None => None,
68        };
69        Parser { path, tokens: PushbackIter::new(tokens), doc_env, }
70    }
71
72    /// Creates a parser with the root module of documentation without the current module of
73    /// documentation.
74    ///
75    /// See [`new_with_doc_root_mod_and_doc_current_mod`](Self::new_with_doc_root_mod_and_doc_current_mod).
76    pub fn new_with_doc_root_mod(path: Arc<String>, tokens: &'a mut dyn DocIterator<Item = Result<(Token, Pos)>>, doc_root_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>) -> Self
77    { Self::new_with_doc_root_mod_and_doc_current_mod(path, tokens, doc_root_mod, None) }
78
79    /// Creates a parser.
80    ///
81    /// See [`new_with_doc_root_mod_and_doc_current_mod`](Self::new_with_doc_root_mod_and_doc_current_mod).
82    pub fn new(path: Arc<String>, tokens: &'a mut dyn DocIterator<Item = Result<(Token, Pos)>>) -> Self
83    { Self::new_with_doc_root_mod(path, tokens, None) }
84    
85    /// Returns the root module of documentation if the parser has the root module of
86    /// documentation, otherwise `None`.
87    pub fn doc_root_mod(&self) -> Option<&Arc<RwLock<ModNode<String, Option<String>>>>>
88    { 
89        match &self.doc_env {
90            Some(doc_env) => Some(&doc_env.root_mod),
91            None => None,
92        }
93    }
94    
95    /// Parses the tokens to a script tree.
96    pub fn parse(&mut self) -> Result<Tree>
97    {
98        let nodes = self.parse_zero_or_more_with_newlines(&[None], ParserEofFlag::Repetition, Self::parse_node)?;
99        match self.tokens.next().transpose()? {
100            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
101            None => Ok(Tree(nodes)),
102        }
103    }
104    
105    fn parse_newline(&mut self) -> Result<()>
106    {
107        match self.tokens.next().transpose()? {
108            Some((Token::Newline, _)) => Ok(()),
109            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
110            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
111        }
112    }
113
114    fn parse_newlines(&mut self) -> Result<()>
115    {
116        loop {
117            match self.tokens.next().transpose()? {
118                Some((Token::Newline, _)) => (),
119                Some((token, pos)) => {
120                    self.tokens.undo(Ok((token, pos)));
121                    break;
122                },
123                None => break,
124            }
125        }
126        Ok(())
127    }
128    
129    fn parse_zero_or_more_with_newlines<T, F>(&mut self, end_tokens: &[Option<Token>], flag: ParserEofFlag, mut f: F) -> Result<Vec<T>>
130        where F: FnMut(&mut Self) -> Result<T>
131    {
132        let mut xs: Vec<T> = Vec::new();
133        self.parse_newlines()?;
134        loop {
135            match self.tokens.next().transpose()? {
136                Some((token, pos)) if end_tokens.contains(&Some(token.clone())) => {
137                    self.tokens.undo(Ok((token, pos)));
138                    break;
139                },
140                Some((token, pos)) => self.tokens.undo(Ok((token, pos))),
141                None if end_tokens.contains(&None) => break,
142                None => return Err(Error::ParserEof(self.path.clone(), flag)),
143            }
144            xs.push(f(self)?);
145            match self.tokens.next().transpose()? {
146                Some((Token::Newline, _)) => (),
147                Some((token, pos)) => {
148                    self.tokens.undo(Ok((token, pos)));
149                    break;
150                },
151                None => break,
152            }
153            self.parse_newlines()?;
154        }
155        Ok(xs)
156    }
157
158    fn parse_zero_or_more_with_commas<T, F>(&mut self, end_tokens: &[Option<Token>], flag: ParserEofFlag, mut f: F) -> Result<Vec<T>>
159        where F: FnMut(&mut Self) -> Result<T>
160    {
161        let mut xs: Vec<T> = Vec::new();
162        loop {
163            match self.tokens.next().transpose()? {
164                Some((token, pos)) if end_tokens.contains(&Some(token.clone())) => {
165                    self.tokens.undo(Ok((token, pos)));
166                    break;
167                },
168                Some((token, pos)) => self.tokens.undo(Ok((token, pos))),
169                None if end_tokens.contains(&None) => break,
170                None => return Err(Error::ParserEof(self.path.clone(), flag)),
171            }
172            xs.push(f(self)?);
173            match self.tokens.next().transpose()? {
174                Some((Token::Comma, _)) => (),
175                Some((token, pos)) => {
176                    self.tokens.undo(Ok((token, pos)));
177                    break;
178                },
179                None => break,
180            }
181        }
182        Ok(xs)
183    }
184
185    fn parse_node(&mut self) -> Result<Node>
186    {
187        match self.tokens.next().transpose()? {
188            Some((token @ (Token::Function | Token::Module), pos)) => {
189                self.tokens.undo(Ok((token, pos)));
190                Ok(Node::Def(self.parse_def()?))
191            },
192            Some((token, pos)) => {
193                self.tokens.undo(Ok((token, pos)));
194                Ok(Node::Stat(self.parse_stat()?))
195            },
196            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
197        }
198    }
199    
200    fn parse_def(&mut self) -> Result<Box<Def>>
201    {
202        match self.tokens.next().transpose()? {
203            Some((Token::Module, pos)) => {
204                let ident = self.parse_ident()?.0;
205                match &mut self.doc_env {
206                    Some(doc_env) => {
207                        let doc = self.tokens.iter_mut().take_doc();
208                        let new_mod: Arc<RwLock<ModNode<String, Option<String>>>> = Arc::new(RwLock::new(ModNode::new(doc)));
209                        ModNode::add_mod(&doc_env.current_mod, ident.clone(), new_mod.clone())?;
210                        doc_env.current_mod = new_mod;
211                    },
212                    None => (),
213                }
214                self.parse_newline()?;
215                let nodes = self.parse_zero_or_more_with_newlines(&[Some(Token::End)], ParserEofFlag::Repetition, Self::parse_node)?;
216                match self.tokens.next().transpose()? {
217                    Some((Token::End, _)) => {
218                        match &mut self.doc_env {
219                            Some(doc_env) => {
220                                let parent = {
221                                    let current_mod_g = rw_lock_read(&*doc_env.current_mod)?;
222                                    current_mod_g.parent()
223                                };
224                                match parent {
225                                    Some(parent) => doc_env.current_mod = parent,
226                                    None => (),
227                                }
228                            },
229                            None => (),
230                        }
231                        Ok(Box::new(Def::Mod(ident, Box::new(Mod(nodes)), pos)))
232                    },
233                    Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unexpected token"))),
234                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
235                }
236            },
237            Some((Token::Function, pos)) => {
238                let ident = self.parse_ident()?.0;
239                match &mut self.doc_env {
240                    Some(doc_env) => {
241                        match self.tokens.iter_mut().take_doc() {
242                            Some(doc) => {
243                                let mut current_mod_g = rw_lock_write(&*doc_env.current_mod)?;
244                                current_mod_g.add_var(ident.clone(), doc);
245                            },
246                            None => (),
247                        }
248                    },
249                    None => (),
250                }
251                match self.tokens.next().transpose()? {
252                    Some((Token::LParen, _)) => {
253                        let args = self.parse_zero_or_more_with_commas(&[Some(Token::RParen)], ParserEofFlag::NoRepetition, Self::parse_arg)?;
254                        match self.tokens.next().transpose()? {
255                            Some((Token::RParen, _)) => (),
256                            Some((_, pos2)) => return Err(Error::Parser(pos2, String::from("unclosed parenthesis"))),
257                            None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
258                        }
259                        self.parse_newline()?;
260                        let stats = self.parse_zero_or_more_with_newlines(&[Some(Token::End)], ParserEofFlag::Repetition, Self::parse_stat)?;
261                        match self.tokens.next().transpose()? {
262                            Some((Token::End, _)) => Ok(Box::new(Def::Fun(ident, Arc::new(Fun(args, stats)), pos))),
263                            Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unexpected token"))),
264                            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
265                        }
266                    },
267                    Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unexpected token"))),
268                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
269                }
270            },
271            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
272            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
273        }
274    }
275    
276    fn parse_arg(&mut self) -> Result<Arg>
277    {
278        let (ident, pos) = self.parse_ident()?;
279        Ok(Arg(ident, pos))
280    }
281    
282    fn parse_stat(&mut self) -> Result<Box<Stat>>
283    {
284        match self.tokens.next().transpose()? {
285            Some((Token::If, pos)) => {
286                let if_expr = self.parse_expr()?;
287                self.parse_newline()?;
288                let if_stats = self.parse_zero_or_more_with_newlines(&[Some(Token::End), Some(Token::Else)], ParserEofFlag::Repetition, Self::parse_stat)?;
289                let mut else_if_pairs: Vec<(Box<Expr>, Vec<Box<Stat>>)> = Vec::new();
290                loop {
291                    match self.tokens.next().transpose()? {
292                        Some((token2 @ Token::Else, pos2)) => {
293                            match self.tokens.next().transpose()? {
294                                Some((Token::If, _)) => {
295                                    let else_if_expr = self.parse_expr()?;
296                                    self.parse_newline()?;
297                                    let else_if_stats = self.parse_zero_or_more_with_newlines(&[Some(Token::End), Some(Token::Else)], ParserEofFlag::Repetition, Self::parse_stat)?;
298                                    else_if_pairs.push((else_if_expr, else_if_stats));
299                                },
300                                Some((token3, pos3)) => {
301                                    self.tokens.undo(Ok((token3, pos3)));
302                                    self.tokens.undo(Ok((token2, pos2)));
303                                    break;
304                                },
305                                None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
306                            }
307                        },
308                        Some((token2, pos2)) => {
309                            self.tokens.undo(Ok((token2, pos2)));
310                            break;
311                        },
312                        None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
313                    }
314                }
315                match self.tokens.next().transpose()? {
316                    Some((Token::Else, _)) => {
317                        self.parse_newline()?;
318                        let else_stats = self.parse_zero_or_more_with_newlines(&[Some(Token::End)], ParserEofFlag::Repetition, Self::parse_stat)?;
319                        match self.tokens.next().transpose()? {
320                            Some((Token::End, _)) => (),
321                            Some((_, pos3)) => return Err(Error::Parser(pos3, String::from("unexpected token"))),
322                            None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
323                        }
324                        Ok(Box::new(Stat::If(if_expr, if_stats, else_if_pairs, Some(else_stats), pos)))
325                    },
326                    Some((Token::End, _)) => Ok(Box::new(Stat::If(if_expr, if_stats, else_if_pairs, None, pos))),
327                    Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unexpected token"))),
328                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
329                }
330            },
331            Some((Token::For, pos)) => {
332                let ident = self.parse_ident()?.0;
333                self.parse_in()?;
334                let expr = self.parse_expr()?;
335                self.parse_newline()?;
336                let stats = self.parse_zero_or_more_with_newlines(&[Some(Token::End)], ParserEofFlag::Repetition, Self::parse_stat)?;
337                match self.tokens.next().transpose()? {
338                    Some((Token::End, _)) => Ok(Box::new(Stat::For(ident, expr, stats, pos))),
339                    Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unexpected token"))),
340                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
341                }
342            },
343            Some((Token::While, pos)) => {
344                let expr = self.parse_expr()?;
345                self.parse_newline()?;
346                let stats = self.parse_zero_or_more_with_newlines(&[Some(Token::End)], ParserEofFlag::Repetition, Self::parse_stat)?;
347                match self.tokens.next().transpose()? {
348                    Some((Token::End, _)) => Ok(Box::new(Stat::While(expr, stats, pos))),
349                    Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unexpected token"))),
350                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
351                }
352            },
353            Some((Token::Break, pos)) => Ok(Box::new(Stat::Break(pos))),
354            Some((Token::Continue, pos)) => Ok(Box::new(Stat::Continue(pos))),
355            Some((Token::Return, pos)) => {
356                match self.tokens.next().transpose()? {
357                    Some((token2 @ (Token::Newline | Token::Else | Token::End), pos2)) => {
358                        self.tokens.undo(Ok((token2, pos2)));
359                        Ok(Box::new(Stat::Return(None, pos)))
360                    },
361                    Some((token2, pos2)) => {
362                        self.tokens.undo(Ok((token2, pos2)));
363                        Ok(Box::new(Stat::Return(Some(self.parse_expr()?), pos)))
364                    },
365                    None => Ok(Box::new(Stat::Return(None, pos))),
366                }
367            },
368            Some((Token::Quit, pos)) => Ok(Box::new(Stat::Quit(pos))),
369            Some((token, pos)) => {
370                self.tokens.undo(Ok((token, pos)));
371                let expr = self.parse_expr()?;
372                let expr_pos = expr.pos().clone();
373                match self.tokens.next().transpose()? {
374                    Some((Token::Eq, _)) => {
375                        match &mut self.doc_env {
376                            Some(doc_env) => {
377                                let pair = match &*expr {
378                                    Expr::Var(Name::Abs(idents, ident), _) => {
379                                        match ModNode::mod_from(&doc_env.root_mod, idents.as_slice(), false)? {
380                                            Some(tmp_mod) => Some((tmp_mod, ident.clone())),
381                                            None => None,
382                                        }
383                                    },
384                                    Expr::Var(Name::Rel(idents, ident), _) => {
385                                        match ModNode::mod_from(&doc_env.current_mod, idents.as_slice(), true)? {
386                                            Some(tmp_mod) => Some((tmp_mod, ident.clone())),
387                                            None => {
388                                                match ModNode::mod_from(&doc_env.root_mod, idents.as_slice(), false)? {
389                                                    Some(tmp_mod) => Some((tmp_mod, ident.clone())),
390                                                    None => None,
391                                                }
392                                            },
393                                        }
394                                    },
395                                    Expr::Var(Name::Var(ident), _) => Some((doc_env.current_mod.clone(), ident.clone())),
396                                    _ => None,
397                                };
398                                match pair {
399                                    Some((mod1, ident)) => {
400                                        match self.tokens.iter_mut().take_doc() {
401                                            Some(doc) => {
402                                                let mut mod_g = rw_lock_write(&*mod1)?;
403                                                mod_g.add_var(ident, doc);
404                                            },
405                                            None => (),
406                                        }
407                                    },
408                                    None => (),
409                                }
410                            },
411                            None => (),
412                        }
413                        Ok(Box::new(Stat::Assign(expr, self.parse_expr()?, expr_pos)))
414                    },
415                    Some((token2, pos2)) => {
416                        self.tokens.undo(Ok((token2, pos2)));
417                        Ok(Box::new(Stat::Expr(expr, expr_pos)))
418                    },
419                    None => Ok(Box::new(Stat::Expr(expr, expr_pos))),
420                }
421            },
422            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
423        }
424    }
425    
426    fn parse_expr11(&mut self) -> Result<Box<Expr>>
427    {
428        match self.tokens.next().transpose()? {
429            Some((Token::LParen, pos)) => {
430                let mut expr = self.parse_expr()?;
431                expr.set_pos(pos);
432                match self.tokens.next().transpose()? {
433                    Some((Token::RParen, _)) => (),
434                    Some((_, pos2)) => return Err(Error::Parser(pos2, String::from("unclosed parenthesis"))),
435                    None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
436                }
437                Ok(expr)
438            },
439            Some((token @ (Token::ColonColon | Token::Root | Token::Ident(_)), pos)) => {
440                self.tokens.undo(Ok((token, pos)));
441                let (name, name_pos) = self.parse_name()?;
442                Ok(Box::new(Expr::Var(name, name_pos)))
443            },
444            Some((token, pos)) => {
445                self.tokens.undo(Ok((token, pos)));
446                let (lit, lit_pos) = self.parse_lit()?;
447                Ok(Box::new(Expr::Lit(lit, lit_pos)))
448            },
449            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
450        }
451    }
452
453    fn parse_expr10(&mut self) -> Result<Box<Expr>>
454    {
455        let mut expr = self.parse_expr11()?;
456        loop {
457            let expr_pos = expr.pos().clone();
458            match self.tokens.next().transpose()? {
459                Some((Token::LParen, _)) => {
460                    expr = Box::new(Expr::App(expr, self.parse_zero_or_more_with_commas(&[Some(Token::RParen)], ParserEofFlag::NoRepetition, Self::parse_expr)?, expr_pos));
461                    match self.tokens.next().transpose()? {
462                        Some((Token::RParen, _)) => (),
463                        Some((_, pos2)) => return Err(Error::Parser(pos2, String::from("unclosed parenthesis"))),
464                        None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
465                    }
466                },
467                Some((Token::LBracket, _)) => {
468                    expr = Box::new(Expr::BinOp(BinOp::Index, expr, self.parse_expr()?, expr_pos));
469                    match self.tokens.next().transpose()? {
470                        Some((Token::RBracket, _)) => (),
471                        Some((_, pos2)) => return Err(Error::Parser(pos2, String::from("unclosed bracket"))),
472                        None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
473                    }
474                },
475                Some((Token::Dot, _)) => expr = Box::new(Expr::Field(expr, self.parse_ident()?.0, expr_pos)),
476                Some((token, pos)) => {
477                    self.tokens.undo(Ok((token, pos)));
478                    break;
479                },
480                None => break,
481            }
482        }
483        Ok(expr)
484    }
485    
486    fn parse_expr9(&mut self) -> Result<Box<Expr>>
487    {
488        let mut expr = self.parse_expr10()?;
489        let expr_pos = expr.pos().clone();
490        loop {
491            match self.tokens.next().transpose()? {
492                Some((Token::Ques, _)) => expr = Box::new(Expr::PropagateError(expr, expr_pos.clone())),
493                Some((token, pos)) => {
494                    self.tokens.undo(Ok((token, pos)));
495                    break;
496                },
497                None => break,
498            }
499        }
500        Ok(expr)
501    }
502    
503    fn parse_expr8(&mut self) -> Result<Box<Expr>>
504    {
505        match self.tokens.next().transpose()? {
506            Some((Token::Minus, pos)) => Ok(Box::new(Expr::UnaryOp(UnaryOp::Neg, self.parse_expr8()?, pos))),
507            Some((Token::DotMinus, pos)) => Ok(Box::new(Expr::UnaryOp(UnaryOp::DotNeg, self.parse_expr8()?, pos))),
508            Some((Token::Not, pos)) => Ok(Box::new(Expr::UnaryOp(UnaryOp::Not, self.parse_expr8()?, pos))),
509            Some((token, pos)) => {
510                let expr_pos = pos.clone();
511                self.tokens.undo(Ok((token, pos)));
512                let mut expr = self.parse_expr9()?;
513                loop {
514                    match self.tokens.next().transpose()? {
515                        Some((Token::Apos, _)) => expr = Box::new(Expr::UnaryOp(UnaryOp::Transpose, expr, expr_pos.clone())),
516                        Some((token2, pos2)) => {
517                            self.tokens.undo(Ok((token2, pos2)));
518                            break;
519                        },
520                        None => break,
521                    }
522                }
523                Ok(expr)
524            },
525            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
526        }
527    }
528    
529    fn parse_expr7(&mut self) -> Result<Box<Expr>>
530    {
531        let mut expr = self.parse_expr8()?;
532        loop {
533            let expr_pos = expr.pos().clone();
534            match self.tokens.next().transpose()? {
535                Some((Token::Star, _)) => expr = Box::new(Expr::BinOp(BinOp::Mul, expr, self.parse_expr8()?, expr_pos)),
536                Some((Token::DotStar, _)) => expr = Box::new(Expr::BinOp(BinOp::DotMul, expr, self.parse_expr8()?, expr_pos)),
537                Some((Token::Slash, _)) => expr = Box::new(Expr::BinOp(BinOp::Div, expr, self.parse_expr8()?, expr_pos)),
538                Some((Token::DotSlash, _)) => expr = Box::new(Expr::BinOp(BinOp::DotDiv, expr, self.parse_expr8()?, expr_pos)),
539                Some((token, pos)) => {
540                    self.tokens.undo(Ok((token, pos)));
541                    break;
542                },
543                None => break,
544            }
545        }
546        Ok(expr)
547    }
548    
549    fn parse_expr6(&mut self) -> Result<Box<Expr>>
550    {
551        let mut expr = self.parse_expr7()?;
552        loop {
553            let expr_pos = expr.pos().clone();
554            match self.tokens.next().transpose()? {
555                Some((Token::Plus, _)) => expr = Box::new(Expr::BinOp(BinOp::Add, expr, self.parse_expr7()?, expr_pos)),
556                Some((Token::DotPlus, _)) => expr = Box::new(Expr::BinOp(BinOp::DotAdd, expr, self.parse_expr7()?, expr_pos)),
557                Some((Token::Minus, _)) => expr = Box::new(Expr::BinOp(BinOp::Sub, expr, self.parse_expr7()?, expr_pos)),
558                Some((Token::DotMinus, _)) => expr = Box::new(Expr::BinOp(BinOp::DotSub, expr, self.parse_expr7()?, expr_pos)),
559                Some((token, pos)) => {
560                    self.tokens.undo(Ok((token, pos)));
561                    break;
562                },
563                None => break,
564            }
565        }
566        Ok(expr)
567    }
568    
569    fn parse_expr5(&mut self) -> Result<Box<Expr>>
570    {
571        let mut expr = self.parse_expr6()?;
572        let expr_pos = expr.pos().clone();
573        match self.tokens.next().transpose()? {
574            Some((Token::To, _)) => {
575                let expr2 = self.parse_expr6()?;
576                let expr3 = match self.tokens.next().transpose()? {
577                    Some((Token::By, _)) => Some(self.parse_expr6()?),
578                    Some((token2, pos2)) => {
579                        self.tokens.undo(Ok((token2, pos2)));
580                        None
581                    },
582                    None => None,
583                };
584                expr = Box::new(Expr::Range(expr, expr2, expr3, expr_pos));
585            },
586            Some((token, pos)) => self.tokens.undo(Ok((token, pos))),
587            None => (),
588        }
589        Ok(expr)
590    }
591
592    fn parse_expr4(&mut self) -> Result<Box<Expr>>
593    {
594        let mut expr = self.parse_expr5()?;
595        loop {
596            let expr_pos = expr.pos().clone();
597            match self.tokens.next().transpose()? {
598                Some((Token::Lt, _)) => expr = Box::new(Expr::BinOp(BinOp::Lt, expr, self.parse_expr5()?, expr_pos)),
599                Some((Token::GtEq, _)) => expr = Box::new(Expr::BinOp(BinOp::Ge, expr, self.parse_expr5()?, expr_pos)),
600                Some((Token::Gt, _)) => expr = Box::new(Expr::BinOp(BinOp::Gt, expr, self.parse_expr5()?, expr_pos)),
601                Some((Token::LtEq, _)) => expr = Box::new(Expr::BinOp(BinOp::Le, expr, self.parse_expr5()?, expr_pos)),
602                Some((token, pos)) => {
603                    self.tokens.undo(Ok((token, pos)));
604                    break;
605                },
606                None => break,
607            }
608        }
609        Ok(expr)
610    }
611    
612    fn parse_expr3(&mut self) -> Result<Box<Expr>>
613    {
614        let mut expr = self.parse_expr4()?;
615        loop {
616            let expr_pos = expr.pos().clone();
617            match self.tokens.next().transpose()? {
618                Some((Token::EqEq, _)) => expr = Box::new(Expr::BinOp(BinOp::Eq, expr, self.parse_expr4()?, expr_pos)),
619                Some((Token::ExEq, _)) => expr = Box::new(Expr::BinOp(BinOp::Ne, expr, self.parse_expr4()?, expr_pos)),
620                Some((token, pos)) => {
621                    self.tokens.undo(Ok((token, pos)));
622                    break;
623                },
624                None => break,
625            }
626        }
627        Ok(expr)
628    }
629
630    fn parse_expr2(&mut self) -> Result<Box<Expr>>
631    {
632        let mut expr = self.parse_expr3()?;
633        loop {
634            let expr_pos = expr.pos().clone();
635            match self.tokens.next().transpose()? {
636                Some((Token::And, _)) => expr = Box::new(Expr::And(expr, self.parse_expr3()?, expr_pos)),
637                Some((token, pos)) => {
638                    self.tokens.undo(Ok((token, pos)));
639                    break;
640                },
641                None => break,
642            }
643        }
644        Ok(expr)
645    }
646    
647    fn parse_expr(&mut self) -> Result<Box<Expr>>
648    {
649        let mut expr = self.parse_expr2()?;
650        loop {
651            let expr_pos = expr.pos().clone();
652            match self.tokens.next().transpose()? {
653                Some((Token::Or, _)) => expr = Box::new(Expr::Or(expr, self.parse_expr2()?, expr_pos)),
654                Some((token, pos)) => {
655                    self.tokens.undo(Ok((token, pos)));
656                    break;
657                },
658                None => break,
659            }
660        }
661        Ok(expr)
662    }
663
664    fn parse_lit(&mut self) -> Result<(Lit, Pos)>
665    {
666        match self.tokens.next().transpose()? {
667            Some((Token::None, pos)) => Ok((Lit::None, pos)),
668            Some((Token::False, pos)) => Ok((Lit::Bool(false), pos)),
669            Some((Token::True, pos)) => Ok((Lit::Bool(true), pos)),
670            Some((Token::Int(n), pos)) => Ok((Lit::Int(n), pos)),
671            Some((Token::Float(n), pos)) => Ok((Lit::Float(n), pos)),
672            Some((Token::Inf, pos)) => Ok((Lit::Float(f32::INFINITY), pos)),
673            Some((Token::Nan, pos)) => Ok((Lit::Float(f32::NAN), pos)),
674            Some((Token::String(s), pos)) => Ok((Lit::String(s), pos)),
675            Some((Token::LBracket, pos)) => {
676                self.parse_newlines()?;
677                match self.tokens.next().transpose()? {
678                    Some((Token::RBracket, _)) => Ok((Lit::Matrix(Vec::new()), pos)),
679                    Some((token2, pos2)) => {
680                        self.tokens.undo(Ok((token2, pos2)));
681                        let matrix_row = self.parse_matrix_row()?;
682                        let lit = match self.tokens.next().transpose()? {
683                            Some((Token::Newline, _)) => {
684                                self.parse_newlines()?;
685                                match self.tokens.next().transpose()? {
686                                    Some((Token::Fill, _)) => {
687                                        let expr = self.parse_expr()?;
688                                        self.parse_newlines()?;
689                                        Lit::FilledMatrix(matrix_row, expr)
690                                    },
691                                    Some((token4, pos4))=> {
692                                        self.tokens.undo(Ok((token4, pos4)));
693                                        let mut matrix_rows = vec![matrix_row];
694                                        matrix_rows.extend_from_slice(self.parse_zero_or_more_with_newlines(&[Some(Token::RBracket)], ParserEofFlag::Repetition, Self::parse_matrix_row)?.as_slice());
695                                        Lit::Matrix(matrix_rows)
696                                    },
697                                    None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
698                                }
699                            },
700                            Some((token3, pos3)) => {
701                                self.tokens.undo(Ok((token3, pos3)));
702                                Lit::Matrix(vec![matrix_row])
703                            },
704                            None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
705                        };
706                        match self.tokens.next().transpose()? {
707                            Some((Token::RBracket, _)) => Ok((lit, pos)),
708                            Some((_, pos3)) => Err(Error::Parser(pos3, String::from("unclosed bracket"))),
709                            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
710                        }
711                    },
712                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
713                }
714            },
715            Some((Token::DotLBracket, pos)) => {
716                self.parse_newlines()?;
717                match self.tokens.next().transpose()? {
718                    Some((Token::DotRBracket, _)) => Ok((Lit::Array(Vec::new()), pos)),
719                    Some((token2, pos2)) => {
720                        self.tokens.undo(Ok((token2, pos2)));
721                        let lit = match self.parse_fillable_exprs(&[Some(Token::DotRBracket), Some(Token::Newline)])? {
722                            FillableExprs::Exprs(exprs) => Lit::Array(exprs),
723                            FillableExprs::FilledExprs(expr, expr2) => Lit::FilledArray(expr, expr2),
724                        };
725                        self.parse_newlines()?;
726                        match self.tokens.next().transpose()? {
727                            Some((Token::DotRBracket, _)) => Ok((lit, pos)),
728                            Some((_, pos3)) => Err(Error::Parser(pos3, String::from("unclosed dot bracket"))),
729                            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
730                        }
731                    },
732                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
733                }
734            },
735            Some((Token::LBrace, pos)) => {
736                let field_pairs = self.parse_zero_or_more_with_newlines(&[Some(Token::RBrace)], ParserEofFlag::Repetition, Self::parse_field_pair)?;
737                match self.tokens.next().transpose()? {
738                    Some((Token::RBrace, _)) => Ok((Lit::Struct(field_pairs), pos)),
739                    Some((_, pos2)) => Err(Error::Parser(pos2, String::from("unclosed brace"))),
740                    None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
741                }
742            },
743            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
744            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
745        }
746    }
747
748    fn parse_fillable_exprs(&mut self, end_tokens: &[Option<Token>]) -> Result<FillableExprs>
749    {
750        match self.tokens.next().transpose()? {
751            Some((token, _)) if end_tokens.contains(&Some(token.clone())) => Ok(FillableExprs::Exprs(Vec::new())),
752            Some((token, pos)) => {
753                self.tokens.undo(Ok((token, pos)));
754                let expr = self.parse_expr()?;
755                match self.tokens.next().transpose()? {
756                    Some((Token::Comma, _)) => {
757                        let mut exprs = vec![expr];
758                        exprs.extend_from_slice(self.parse_zero_or_more_with_commas(end_tokens, ParserEofFlag::Repetition, Self::parse_expr)?.as_slice());
759                        Ok(FillableExprs::Exprs(exprs))
760                    },
761                    Some((Token::Fill, _)) => Ok(FillableExprs::FilledExprs(expr, self.parse_expr()?)),
762                    Some((token2, pos2)) => {
763                        self.tokens.undo(Ok((token2, pos2)));
764                        Ok(FillableExprs::Exprs(vec![expr]))
765                    },
766                    None => Ok(FillableExprs::Exprs(vec![expr]))
767                }
768            },
769            None if end_tokens.contains(&None) => Ok(FillableExprs::Exprs(Vec::new())),
770            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::Repetition)),
771        }
772    }
773
774    fn parse_matrix_row(&mut self) -> Result<MatrixRow>
775    {
776        match self.parse_fillable_exprs(&[Some(Token::RBracket), Some(Token::Newline)])? {
777            FillableExprs::Exprs(exprs) => Ok(MatrixRow::Row(exprs)),
778            FillableExprs::FilledExprs(expr, expr2) => Ok(MatrixRow::FilledRow(expr, expr2)),
779        }
780    }
781    
782    fn parse_field_pair(&mut self) -> Result<FieldPair>
783    {
784        let (ident, pos) = self.parse_ident()?;
785        self.parse_colon()?;
786        Ok(FieldPair(ident, self.parse_expr()?, pos))
787    }
788    
789    fn parse_name(&mut self) -> Result<(Name, Pos)>
790    {
791        let mut idents: Vec<String> = Vec::new();
792        let mut last_ident = String::new();
793        let mut is_last_ident = false;
794        let mut name_pos = Pos::new(self.path.clone(), 1, 1);
795        let mut is_name_pos = false;
796        let mut is_first_colon_colon = false;
797        let mut is_root = false;
798        match self.tokens.next().transpose()? {
799            Some((Token::ColonColon, pos)) => {
800                name_pos = pos.clone();
801                is_name_pos = true;
802                is_first_colon_colon = true;
803            },
804            Some((token, pos)) => self.tokens.undo(Ok((token, pos))),
805            None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
806        }
807        match self.tokens.next().transpose()? {
808            Some((Token::Root, pos)) => {
809                if !is_name_pos {
810                    name_pos = pos;
811                }
812                is_root = true
813            },
814            Some((Token::Ident(ident), pos)) => {
815                if !is_name_pos {
816                    name_pos = pos;
817                }
818                last_ident = ident;
819                is_last_ident = true;
820            },
821            Some((_, pos)) => return Err(Error::Parser(pos, String::from("unexpected token"))),
822            None => return Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
823        }
824        loop {
825            match self.tokens.next().transpose()? {
826                Some((Token::ColonColon, _)) => (),
827                Some((token, pos)) => {
828                    self.tokens.undo(Ok((token, pos)));
829                    break;
830                },
831                None => break,
832            }
833            if is_last_ident {
834                idents.push(last_ident.clone());
835            }
836            last_ident = self.parse_ident()?.0;
837            is_last_ident = true;
838        }
839        if !is_last_ident {
840            return Err(Error::Parser(name_pos, String::from("no last identifier")))
841        }
842        if is_root {
843            Ok((Name::Abs(idents, last_ident), name_pos))
844        } else {
845            if idents.is_empty() {
846                if is_first_colon_colon {
847                    Ok((Name::Rel(Vec::new(), last_ident), name_pos))
848                } else {
849                    Ok((Name::Var(last_ident), name_pos))
850                }
851            } else {
852                Ok((Name::Rel(idents, last_ident), name_pos))
853            }
854        }
855    }
856    
857    fn parse_ident(&mut self) -> Result<(String, Pos)>
858    {
859        match self.tokens.next().transpose()? {
860            Some((Token::Ident(ident), pos)) => Ok((ident, pos)),
861            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
862            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
863        }
864    }
865
866    fn parse_colon(&mut self) -> Result<()>
867    {
868        match self.tokens.next().transpose()? {
869            Some((Token::Colon, _)) => Ok(()),
870            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
871            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
872        }
873    }
874
875    fn parse_in(&mut self) -> Result<()>
876    {
877        match self.tokens.next().transpose()? {
878            Some((Token::In, _)) => Ok(()),
879            Some((_, pos)) => Err(Error::Parser(pos, String::from("unexpected token"))),
880            None => Err(Error::ParserEof(self.path.clone(), ParserEofFlag::NoRepetition)),
881        }
882    }
883}
884
885
886/// Parses the script is refered by the path with the root module of documentation and the current
887/// module of documentation.
888///
889/// See [`Parser::new_with_doc_root_mod_and_doc_current_mod`] and [`Parser::parse`].
890pub fn parse_with_doc_root_mod_and_doc_current_mod<P: AsRef<Path>>(path: P, doc_root_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>, doc_current_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>) -> Result<Tree>
891{
892    match File::open(path.as_ref()) {
893        Ok(file) => {
894            let mut r = BufReader::new(file);
895            let mut lexer = Lexer::new_with_doc_flag(Arc::new(path.as_ref().to_string_lossy().into_owned()), &mut r, doc_root_mod.is_some());
896            let parser_path = lexer.path().clone();
897            let tokens: &mut dyn DocIterator<Item = Result<(Token, Pos)>> = &mut lexer;
898            let mut parser = Parser::new_with_doc_root_mod_and_doc_current_mod(parser_path, tokens, doc_root_mod, doc_current_mod);
899            parser.parse()
900        },
901        Err(err) => Err(Error::ParserIo(Arc::new(path.as_ref().to_string_lossy().into_owned()), err)),
902    }
903}
904
905/// Parses the script is refered by the path with the root module of documentation.
906///
907/// See [`Parser::new_with_doc_root_mod_and_doc_current_mod`] and [`Parser::parse`].
908pub fn parse_with_doc_root_mod<P: AsRef<Path>>(path: P, doc_root_mod: Option<Arc<RwLock<ModNode<String, Option<String>>>>>) -> Result<Tree>
909{ parse_with_doc_root_mod_and_doc_current_mod(path, doc_root_mod, None) }
910
911/// Parses the script is refered by the path.
912///
913/// See [`Parser::new_with_doc_root_mod_and_doc_current_mod`] and [`Parser::parse`].
914pub fn parse<P: AsRef<Path>>(path: P) -> Result<Tree>
915{ parse_with_doc_root_mod(path, None) }
916
917#[cfg(test)]
918mod tests;