Skip to main content

fluent_syntax/parser/
runtime.rs

1use super::{
2    core::{Parser, Result},
3    errors::ParserError,
4    slice::Slice,
5};
6use crate::ast;
7
8impl<'s, S> Parser<S>
9where
10    S: Slice<'s>,
11{
12    pub fn parse_runtime(
13        mut self,
14    ) -> std::result::Result<ast::Resource<S>, (ast::Resource<S>, Vec<ParserError>)> {
15        let mut errors = vec![];
16
17        // That default allocation gives the lowest
18        // number of instructions and cycles in ioi.
19        let mut body = Vec::with_capacity(6);
20
21        self.skip_blank_block();
22
23        while self.ptr < self.length {
24            let entry_start = self.ptr;
25            let entry = self.get_entry_runtime(entry_start);
26
27            match entry {
28                Ok(Some(entry)) => {
29                    body.push(entry);
30                }
31                Ok(None) => {}
32                Err(mut err) => {
33                    self.skip_to_next_entry_start();
34                    err.slice = Some(entry_start..self.ptr);
35                    errors.push(err);
36                    let content = self.source.slice(entry_start..self.ptr);
37                    body.push(ast::Entry::Junk { content });
38                }
39            }
40            self.skip_blank_block();
41        }
42
43        if errors.is_empty() {
44            Ok(ast::Resource { body })
45        } else {
46            Err((ast::Resource { body }, errors))
47        }
48    }
49
50    fn get_entry_runtime(&mut self, entry_start: usize) -> Result<Option<ast::Entry<S>>> {
51        let entry = match get_current_byte!(self) {
52            Some(b'#') => {
53                self.skip_comment();
54                None
55            }
56            Some(b'-') => Some(ast::Entry::Term(self.get_term(entry_start)?)),
57            _ => Some(ast::Entry::Message(self.get_message(entry_start)?)),
58        };
59        Ok(entry)
60    }
61}