air_parser/
lib.rs

1#[macro_use]
2extern crate lalrpop_util;
3
4pub mod ast;
5mod lexer;
6mod parser;
7mod sema;
8pub mod symbols;
9pub mod transforms;
10
11pub use self::parser::{ParseError, Parser};
12pub use self::sema::{LexicalScope, SemanticAnalysisError};
13pub use self::symbols::Symbol;
14
15use std::path::Path;
16use std::sync::Arc;
17
18use miden_diagnostics::{CodeMap, DiagnosticsHandler};
19
20/// Parses the provided source and returns the AST.
21pub fn parse(
22    diagnostics: &DiagnosticsHandler,
23    codemap: Arc<CodeMap>,
24    source: &str,
25) -> Result<ast::Program, ParseError> {
26    let parser = Parser::new((), codemap);
27    match parser.parse_string::<ast::Program, _, _>(diagnostics, source) {
28        Ok(ast) => Ok(ast),
29        Err(ParseError::Lexer(err)) => {
30            diagnostics.emit(err);
31            Err(ParseError::Failed)
32        }
33        Err(err) => Err(err),
34    }
35}
36
37/// Parses the provided source and returns the AST.
38pub fn parse_file<P: AsRef<Path>>(
39    diagnostics: &DiagnosticsHandler,
40    codemap: Arc<CodeMap>,
41    source: P,
42) -> Result<ast::Program, ParseError> {
43    let parser = Parser::new((), codemap);
44    match parser.parse_file::<ast::Program, _, _>(diagnostics, source) {
45        Ok(ast) => Ok(ast),
46        Err(ParseError::Lexer(err)) => {
47            diagnostics.emit(err);
48            Err(ParseError::Failed)
49        }
50        Err(err) => Err(err),
51    }
52}
53
54/// Parses the provided source string with a default [CodeMap] and [DiagnosticsHandler].
55///
56/// This is primarily provided for use in tests, you should generally prefer [parse]
57pub fn parse_str(source: &str) -> Result<ast::Program, ParseError> {
58    use miden_diagnostics::{
59        DefaultEmitter, DiagnosticsConfig, Verbosity, term::termcolor::ColorChoice,
60    };
61
62    let codemap = Arc::new(CodeMap::new());
63    let emitter = Arc::new(DefaultEmitter::new(ColorChoice::Auto));
64    let config = DiagnosticsConfig {
65        verbosity: Verbosity::Warning,
66        warnings_as_errors: true,
67        no_warn: false,
68        display: Default::default(),
69    };
70    let diagnostics = DiagnosticsHandler::new(config, codemap.clone(), emitter);
71    parse(&diagnostics, codemap, source)
72}
73
74/// Parses a [Module] from the given path.
75///
76/// This is primarily intended for use in the import resolution phase.
77pub(crate) fn parse_module_from_file<P: AsRef<Path>>(
78    diagnostics: &DiagnosticsHandler,
79    codemap: Arc<CodeMap>,
80    path: P,
81) -> Result<ast::Module, ParseError> {
82    let parser = Parser::new((), codemap);
83    match parser.parse_file::<ast::Module, _, _>(diagnostics, path) {
84        ok @ Ok(_) => ok,
85        Err(ParseError::Lexer(err)) => {
86            diagnostics.emit(err);
87            Err(ParseError::Failed)
88        }
89        err @ Err(_) => err,
90    }
91}
92
93/// Parses a [Module] from a file already in the codemap
94///
95/// This is primarily intended for use in the import resolution phase.
96pub(crate) fn parse_module(
97    diagnostics: &DiagnosticsHandler,
98    codemap: Arc<CodeMap>,
99    source: Arc<miden_diagnostics::SourceFile>,
100) -> Result<ast::Module, ParseError> {
101    let parser = Parser::new((), codemap);
102    match parser.parse::<ast::Module, _>(diagnostics, source) {
103        ok @ Ok(_) => ok,
104        Err(ParseError::Lexer(err)) => {
105            diagnostics.emit(err);
106            Err(ParseError::Failed)
107        }
108        err @ Err(_) => err,
109    }
110}