Skip to main content

mist_parser/
lib.rs

1use pest::Parser;
2use pest_derive::Parser;
3
4pub mod ast;
5pub mod error;
6pub mod parser;
7pub mod rev_mapper;
8
9use ast::*;
10
11use crate::error::{IntoErr, ParseError};
12
13#[derive(Parser)]
14#[grammar = "./src/grammar.pest"]
15pub struct MistParser;
16
17pub fn parse<'a>(source: &'a str) -> Result<Vec<TopLevel>, ParseError<'a, Vec<TopLevel>>> {
18    let mut pairs = MistParser::parse(Rule::program, source)?;
19
20    let mut statements = vec![];
21
22    let mut analyzer = error::AstErrorAnalyzer(None);
23
24    for pair in pairs.next().unwrap().into_inner() {
25        if pair.as_rule() != Rule::EOI {
26            statements.push(analyzer.get(TopLevel::try_from(pair)).get()?);
27        }
28    }
29
30    match analyzer.build(statements) {
31        Ok(v) => Ok(v),
32        Err(e) => Err(ParseError::Ast(e)),
33    }
34}
35
36#[macro_export]
37macro_rules! ast_ensure {
38    ($pair:expr, $rule:expr $(, $rules:expr)* => $body:block) => {
39        if $pair.as_rule() == $rule $(|| $pair.as_rule() == $rules)*
40            $body
41        else {
42            Err(AstError {
43                span: $pair.as_span(),
44                error_code: crate::error::ErrorCode::AstGenBug,
45                error_message: format!("Possible bug: expected {:?}, got {:?}", $rule, $pair.as_rule()),
46                recovered: None,
47            })
48        }
49    };
50}
51
52#[macro_export]
53macro_rules! ast_expr {
54    (use $r:expr, $($v:expr),* $(,)?) => {{
55        let mut analyzer = $crate::error::AstErrorAnalyzer(None);
56
57        $(
58            analyzer.get($v).get()?;
59        )*
60
61        analyzer.build($r)
62    }};
63
64    ($($item:ident)::+ { $($k:ident: $v:expr),* $(,)? }) => {{
65        let mut analyzer = $crate::error::AstErrorAnalyzer(None);
66
67        let v = $($item)::+ { $($k: analyzer.get($v).get()?),* };
68
69        analyzer.build(v)
70    }};
71
72    ($($item:ident)::+ ( $($v:expr),* $(,)? )) => {{
73        let mut analyzer = $crate::error::AstErrorAnalyzer(None);
74
75        let v = $($item)::+ ( $(analyzer.get($v).get()?),* );
76
77        analyzer.build(v)
78    }};
79
80    (( $($v:expr),* $(,)? )) => {{
81        let mut analyzer = $crate::error::AstErrorAnalyzer(None);
82
83        let v = ( $(analyzer.get($v).get()?),* );
84
85        analyzer.build(v)
86    }};
87
88    ($($item:ident)::+) => {
89        $($item)::+
90    };
91}