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