tree_builder_macro/
lib.rs1mod regex_builder;
2mod ast_builder;
3mod parser;
4extern crate proc_macro;
5
6use proc_macro::TokenStream;
7use parser::parser_ast::RuleKind;
8use quote::quote;
9use regex::Regex;
10
11use crate::parser::parser_ast::Specification;
12
13trait Parser {
14 fn parse(input: &str) -> Self;
15}
16
17#[proc_macro]
18pub fn build_tree(input: TokenStream) -> TokenStream {
19 let input = input.to_string();
20 let input: Vec<&str> = input.split_whitespace().collect();
21 let input = input.join("");
22 let Specification(mut ast) = match parser::specification(&input){
23 Ok((_, out)) => out,
24 Err(nom::Err::Error(e) | nom::Err::Failure(e)) => panic!("{}", nom::error::convert_error(input.as_str(), e)),
25 _ => panic!("Unknown error. Please report this error on GitHub issues, together with the grammar you used")
26 };
27 let tokens: Vec<proc_macro2::TokenStream> = ast.iter_mut().map(rule_kind_to_stream).collect();
28 quote!{
29 #(#tokens)
30 *
31 }.into()
32}
33
34#[proc_macro]
35pub fn ast_parser_maker(input: TokenStream) -> TokenStream {
36 let comment = Regex::new(r"//.*$").unwrap();
37 let input = input.to_string();
38 let input: Vec<String> = input.split_whitespace().map(|x| comment.replace_all(x, "").to_string()).collect();
39 let input = input.join("");
40 let mut ast = match parser::struct_rule(&input){
41 Ok((_, out)) => out,
42 Err(nom::Err::Error(e) | nom::Err::Failure(e)) => panic!("{}", nom::error::convert_error(input.as_str(), e)),
43 _ => panic!("Unknown error. Please report this error on GitHub issues, together with the grammar you used")
44 };
45 ast_builder::parser_builder::gen_parser(&mut ast, None).into()
46}
47
48
49#[proc_macro]
50pub fn rule(input: TokenStream) -> TokenStream {
51 let input = input.to_string();
52 let input: Vec<&str> = input.split_whitespace().collect();
53 let input = input.join("");
54 let mut ast = match parser::rule(&input){
55 Ok((_, out)) => out,
56 Err(nom::Err::Error(e)) => panic!("{}", nom::error::convert_error(input.as_str(), e)),
57 _ => panic!("Unknown error, please open a github issue which includes your source code")
58 };
59 rule_kind_to_stream(&mut ast).into()
60}
61
62fn rule_kind_to_stream(ast: &mut RuleKind) -> proc_macro2::TokenStream {
63 match ast {
64 RuleKind::StructRule(ref mut ast) => {
65 let tuple_type = ast_builder::ast_from_rule(ast);
66 let parser = ast_builder::parser_builder::gen_parser(ast, None);
67 quote!{
68 #tuple_type
69
70 #parser
71 }.into()
72 },
73 RuleKind::RegexRule(ref mut ast) => {
74 regex_builder::rule(ast).into()
75 }
76 }
77}