mago_syntax/parser/
mod.rs

1use bumpalo::Bump;
2
3use mago_database::file::File;
4use mago_database::file::FileId;
5use mago_database::file::HasFileId;
6use mago_syntax_core::input::Input;
7
8use crate::ast::Program;
9use crate::ast::sequence::Sequence;
10use crate::lexer::Lexer;
11
12use crate::error::ParseError;
13use crate::parser::internal::statement::parse_statement;
14use crate::parser::internal::token_stream::TokenStream;
15
16mod internal;
17
18pub fn parse_file<'arena>(arena: &'arena Bump, file: &File) -> (&'arena Program<'arena>, Option<ParseError>) {
19    parse_file_content(arena, file.file_id(), file.contents.as_ref())
20}
21
22pub fn parse_file_content<'arena>(
23    arena: &'arena Bump,
24    file_id: FileId,
25    content: &str,
26) -> (&'arena Program<'arena>, Option<ParseError>) {
27    let source_text = arena.alloc_str(content);
28    let input = Input::new(file_id, source_text.as_bytes());
29    let lexer = Lexer::new(arena, input);
30
31    let mut stream = TokenStream::new(arena, lexer);
32
33    let mut error = None;
34    let statements = {
35        let mut statements = stream.new_vec();
36
37        loop {
38            match stream.has_reached_eof() {
39                Ok(false) => match parse_statement(&mut stream) {
40                    Ok(statement) => {
41                        statements.push(statement);
42                    }
43                    Err(parse_error) => {
44                        error = Some(parse_error);
45
46                        break;
47                    }
48                },
49                Ok(true) => {
50                    break;
51                }
52                Err(syntax_error) => {
53                    error = Some(ParseError::from(syntax_error));
54
55                    break;
56                }
57            }
58        }
59
60        statements
61    };
62
63    let program = arena.alloc(Program {
64        file_id: stream.file_id(),
65        source_text,
66        statements: Sequence::new(statements),
67        trivia: stream.get_trivia(),
68    });
69
70    (program, error)
71}