No parser crate
parent
6207a7f032
commit
87ca1b13f6
@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "parser"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
nom = "7"
|
||||
syn = "2"
|
||||
quote = "1"
|
||||
@ -1,92 +0,0 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, token::Paren, Expr, Ident, Type, TypeTuple};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Component {
|
||||
// Members(Vec<Component>),
|
||||
Member {
|
||||
tag: Ident,
|
||||
inputs: Vec<Type>,
|
||||
}
|
||||
}
|
||||
|
||||
impl syn::parse::Parse for Component {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
|
||||
// TODO: Handle components with multiple struct members
|
||||
let tag: Ident = input.parse()?;
|
||||
let mut inputs = Vec::new();
|
||||
while let Ok(ty) = input.parse() {
|
||||
inputs.push(ty)
|
||||
}
|
||||
Ok(Component::Member { tag, inputs })
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Macro for generating parsing functions for entity components.
|
||||
///
|
||||
/// ```
|
||||
/// let line = "foo 1.2 2.3";
|
||||
/// let (x, y) = parse!("foo <f32> <f32>")(line).unwrap();
|
||||
/// ```
|
||||
///
|
||||
#[proc_macro]
|
||||
pub fn parse(tokens: TokenStream) -> TokenStream {
|
||||
match parse_macro_input!(tokens as Component) {
|
||||
Component::Member { tag, inputs } => {
|
||||
// For each input value
|
||||
// nom::character::complete::space1,
|
||||
// Match on type to determine parsing function (either float or string likely)
|
||||
// nom::number::complete::float,
|
||||
let parsers = Vec::new();
|
||||
let nom_tuple = quote! {
|
||||
nom::bytes::complete::tag("#tag"),
|
||||
#(nom::character::complete::space1, #parsers),*
|
||||
};
|
||||
|
||||
let parsed_vars = Vec::new();
|
||||
let nom_results = quote! {
|
||||
#(#parsed_vars),*
|
||||
};
|
||||
|
||||
let nom_output_type = quote! { #(#inputs),* };
|
||||
let nom_outputs = quote! {
|
||||
// (x1, x2, ...)
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
|line: &str| -> Result<#nom_output_type, nom::Err<_>> {
|
||||
tuple(#nom_tuple)(line).map(|(_, #nom_results)| #nom_outputs)
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let t = nom::bytes::complete::take_while1(nom::character::is_alphabetic)(todo!()).unwrap();
|
||||
|
||||
// let return_type = todo!();
|
||||
// let method_body = todo!();
|
||||
|
||||
// let return_type = "Result<(f32, f32, f32), nom::Err<()>>";
|
||||
// let method_body = "
|
||||
// nom::sequence::tuple((
|
||||
// nom::bytes::complete::tag(\"thing\"),
|
||||
// nom::character::complete::space1,
|
||||
// nom::number::complete::float,
|
||||
// nom::character::complete::space1,
|
||||
// nom::number::complete::float,
|
||||
// nom::character::complete::space1,
|
||||
// nom::number::complete::float
|
||||
// ))(line)
|
||||
// .map(|(_, (_, _, x, _, y, _, z))| {
|
||||
// (x, y, z)
|
||||
// })
|
||||
// ";
|
||||
|
||||
// let lambda = format!("|line: &str| -> {} {{ {} }}", return_type, method_body);
|
||||
|
||||
// lambda.parse().unwrap()
|
||||
@ -1,7 +0,0 @@
|
||||
use parser::parse;
|
||||
|
||||
fn main() {
|
||||
let line = "thing 1.23 3.45 5.67";
|
||||
let f = parse!(thing f32 f32 f32);
|
||||
let (_x, _y, _z) = f(line).unwrap();
|
||||
}
|
||||
Loading…
Reference in New Issue