regen/
lib.rs

1//! # Regen
2//!
3//! Regen is a language that defines a language. See [README](https://github.com/Pistonite/regen-lang) on GitHub
4
5use crate::core::Language;
6
7use sdk::{ASTParser, CreateParseTree, Error, ParseTreeResult, TokenStream};
8
9pub mod core;
10pub mod dynamic;
11pub mod emit;
12pub mod grammar;
13pub mod sdk;
14
15/// Create a language from a grammar string
16///
17/// This is a convienience wrapper for the underlying lexer and parser.
18/// It is used by the CLI and does not have many options.
19///
20/// If you need more control over the language creation process, see the source code
21/// and use the underlying parser directly.
22pub fn parse_language_from_grammar(
23    grammar: &str,
24    stack_size: usize,
25) -> Result<Language, Vec<Error>> {
26    // Parse the language from the grammar
27    let lex_output = grammar::tokenize(grammar);
28    let mut ts = TokenStream::new(&lex_output.tokens, stack_size);
29    let ast_parser = grammar::Parser;
30    let asts = match ast_parser.parse_ast_all(&mut ts) {
31        Err((_, errors)) => {
32            // if errors occur when parsing AST, ignore the ASTs generated and return
33            // the errors
34            return Err(errors);
35        }
36        Ok(asts) => asts,
37    };
38    // create language builder
39    let mut lang_builder = Box::default();
40    let mut errors = vec![];
41    let mut pts = vec![];
42    for ast in &asts {
43        match ast.parse_pt(lang_builder) {
44            ParseTreeResult::Err { ctx, err, .. } => {
45                errors.extend(err);
46                lang_builder = ctx;
47            }
48            ParseTreeResult::Ok { pt, ctx } => {
49                pts.push(pt);
50                lang_builder = ctx;
51            }
52        }
53    }
54    if !errors.is_empty() {
55        return Err(errors);
56    }
57    lang_builder.build(&pts)
58}