Skip to main content

microcad_lang_parse/
lib.rs

1// Copyright © 2026 The µcad authors <info@microcad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Syntax definitions and parser for µcad source code.
5//!
6//! This module includes the components to parse µcad source code into a stream of tokens or abstract syntax tree.
7//!
8//! - Transform source code into a stream of tokens with [`lex`]
9//! - Create an abstract syntax tree from the list of tokens with [`parse`]
10
11/// Abstract syntax tree for µcad files
12pub mod ast;
13mod parser;
14
15/// Source tokens for µcad files
16pub mod tokens;
17
18pub use parser::{ParseContext, ParseError, ParseErrors, parsers};
19
20/// Parse trait.
21pub trait Parse: Sized {
22    /// Parse from a context.
23    ///
24    /// The context also contains the source string.
25    fn parse(context: &ParseContext) -> Result<Self, ParseErrors>;
26}
27
28impl Parse for ast::Source {
29    fn parse(context: &ParseContext) -> Result<Self, ParseErrors> {
30        match context {
31            ParseContext::Element(_) => panic!("Expected parse source context"),
32            ParseContext::Source {
33                url,
34                line_offset,
35                code,
36                ..
37            } => {
38                let ast = crate::parse(code.value())?;
39                let src_ref = context.src_ref(&ast.span);
40
41                Ok(Self {
42                    url: url.clone(),
43                    ast: microcad_lang_base::Refer::new(ast, src_ref),
44                    line_offset: *line_offset,
45                    code: code.clone().map(|s| s.to_string()),
46                })
47            }
48        }
49    }
50}
51
52/// API to parse directly from a string
53pub fn parse(source: &str) -> Result<ast::Program, ParseErrors> {
54    parser::parse(&tokens::lex(source).collect::<Vec<_>>())
55}