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