misty_parser/ast/
mod.rs

1//! Main parser code including AST nodes parsing.
2//!
3//! The main entrypoint of this module is the [parse] function, but other functions are available
4//! to parse individual AST nodes.
5mod data_type;
6mod function;
7mod import;
8mod interface;
9mod misty_enum;
10mod schema;
11
12pub(crate) use data_type::parse_data_type;
13pub(crate) use function::parse_function;
14pub(crate) use import::parse_import;
15pub(crate) use interface::parse_interface;
16pub(crate) use misty_enum::parse_enum;
17pub(crate) use schema::parse_schema;
18
19use crate::ParserError;
20use crate::pest_parser::{MistyPestParser, Rule};
21use misty_ast::{Definition, File};
22use pest::Parser;
23
24#[tracing::instrument(skip(source))]
25pub fn parse(source: &str) -> Result<File, ParserError> {
26    // Try to parse the root rule which is our `file` grammar node.
27    let mut pairs = MistyPestParser::parse(Rule::file, source)
28        .inspect_err(|error| tracing::debug!(?error, "Failed to parse the root rule"))?;
29    let root = pairs
30        .next()
31        .ok_or(ParserError::RootNode)
32        .inspect_err(|error| tracing::debug!(?error, "No root node was found in the source"))?;
33
34    // Iterate over every remaining Pairs inside the root node and extract the imports list and
35    // definitions list.
36    let mut imports = Vec::new();
37    let mut definitions = Vec::new();
38    for pair in root.into_inner() {
39        match pair.as_rule() {
40            Rule::import_stmt => imports.push(parse_import(pair)),
41            Rule::interface_def => definitions.push(Definition::Interface(parse_interface(pair)?)),
42            Rule::schema_def => definitions.push(Definition::Schema(parse_schema(pair)?)),
43            Rule::enum_def => definitions.push(Definition::Enum(parse_enum(pair)?)),
44            Rule::EOI => (),
45            _ => unreachable!(),
46        }
47    }
48
49    // Return the built File node.
50    Ok(File {
51        imports,
52        definitions,
53    })
54}