1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use ara_reporting::Report;
use ara_reporting::ReportFooter;
use ara_source::source::Source;
use ara_source::SourceMap;

use crate::lexer;
use crate::lexer::iterator::TokenIterator;
use crate::lexer::token::Token;
use crate::parser::internal::definition;
use crate::parser::state::State;
use crate::tree::Tree;
use crate::tree::TreeMap;

pub mod issue;

pub(in crate::parser) mod internal;
pub(in crate::parser) mod macros;
pub(in crate::parser) mod result;
pub(in crate::parser) mod state;

pub fn parse_map(map: &SourceMap) -> Result<TreeMap, Box<Report>> {
    let mut trees = vec![];
    let mut reports = vec![];

    for source in &map.sources {
        match parse(source) {
            Ok(tree) => trees.push(tree),
            Err(report) => reports.push(report),
        }
    }

    if !reports.is_empty() {
        let mut issues = vec![];
        for mut report in reports {
            issues.append(&mut report.issues);
        }

        Err(Box::new(Report {
            issues,
            footer: Some(ReportFooter::new(
                "failed to parse source map due to the above issue(s)",
            )),
        }))
    } else {
        Ok(TreeMap::new(trees))
    }
}

pub fn parse(source: &Source) -> Result<Tree, Box<Report>> {
    let tokens = match lexer::lex(source) {
        Ok(tokens) => tokens,
        Err(issue) => {
            return Err(Box::new(Report {
                issues: vec![*issue],
                footer: Some(ReportFooter::new(format!(
                    "failed to parse \"{}\" due to the above issue(s)",
                    source.name(),
                ))),
            }))
        }
    };

    construct(source, &tokens)
}

pub fn construct(source: &Source, tokens: &[Token]) -> Result<Tree, Box<Report>> {
    let mut iterator = TokenIterator::new(tokens);
    let mut state = State::new(source, &mut iterator);

    let definitions = definition::tree(&mut state)?;

    state.finish(Tree::new(source.name(), definitions))
}