mago_parser/
lib.rs

1use mago_ast::Program;
2use mago_ast::sequence::Sequence;
3use mago_interner::ThreadedInterner;
4use mago_lexer::Lexer;
5use mago_lexer::input::Input;
6use mago_source::Source;
7
8use crate::error::ParseError;
9use crate::internal::statement::parse_statement;
10use crate::internal::token_stream::TokenStream;
11
12pub mod error;
13
14mod internal;
15
16pub fn parse_source(interner: &ThreadedInterner, source: &Source) -> (Program, Option<ParseError>) {
17    let content = interner.lookup(&source.content);
18    let lexer = Lexer::new(interner, Input::new(source.identifier, content.as_bytes()));
19
20    construct(interner, lexer)
21}
22
23pub fn parse(interner: &ThreadedInterner, input: Input<'_>) -> (Program, Option<ParseError>) {
24    let lexer = Lexer::new(interner, input);
25
26    construct(interner, lexer)
27}
28
29fn construct<'i>(interner: &'i ThreadedInterner, lexer: Lexer<'_, 'i>) -> (Program, Option<ParseError>) {
30    let mut stream = TokenStream::new(interner, lexer);
31
32    let mut error = None;
33    let statements = {
34        let mut statements = Vec::new();
35
36        loop {
37            match stream.has_reached_eof() {
38                Ok(false) => match parse_statement(&mut stream) {
39                    Ok(statement) => {
40                        statements.push(statement);
41                    }
42                    Err(parse_error) => {
43                        error = Some(parse_error);
44
45                        break;
46                    }
47                },
48                Ok(true) => {
49                    break;
50                }
51                Err(syntax_error) => {
52                    error = Some(ParseError::from(syntax_error));
53
54                    break;
55                }
56            }
57        }
58
59        statements
60    };
61
62    (
63        Program {
64            source: stream.get_position().source,
65            statements: Sequence::new(statements),
66            trivia: stream.get_trivia(),
67        },
68        error,
69    )
70}