generator: Upgrade nom
to 0.7
where parser macros have been removed (#610)
This commit is contained in:
parent
90179c81dc
commit
28a4868dc3
|
@ -8,7 +8,7 @@ edition = "2018"
|
||||||
bindgen = "0.58"
|
bindgen = "0.58"
|
||||||
heck = "0.3"
|
heck = "0.3"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
nom = "6.0"
|
nom = "7.1"
|
||||||
once_cell = "1.7"
|
once_cell = "1.7"
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
|
|
|
@ -3,19 +3,26 @@
|
||||||
|
|
||||||
use heck::{CamelCase, ShoutySnakeCase, SnakeCase};
|
use heck::{CamelCase, ShoutySnakeCase, SnakeCase};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use nom::sequence::pair;
|
||||||
use nom::{
|
use nom::{
|
||||||
alt, char,
|
branch::alt,
|
||||||
character::complete::{digit1, hex_digit1, multispace1},
|
bytes::streaming::tag,
|
||||||
complete, delimited, do_parse, many1, map, named, none_of, one_of, opt, pair, preceded, tag,
|
character::complete::{char, digit1, hex_digit1, multispace1, none_of, one_of},
|
||||||
terminated, value,
|
combinator::{complete, map, opt, value},
|
||||||
|
error::{ParseError, VerboseError},
|
||||||
|
multi::many1,
|
||||||
|
sequence::{delimited, preceded, terminated},
|
||||||
|
IResult, Parser,
|
||||||
};
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use proc_macro2::{Delimiter, Group, Literal, Span, TokenStream, TokenTree};
|
use proc_macro2::{Delimiter, Group, Literal, Span, TokenStream, TokenTree};
|
||||||
use quote::*;
|
use quote::*;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::{
|
||||||
use std::fmt::Display;
|
collections::{BTreeMap, HashMap, HashSet},
|
||||||
use std::path::Path;
|
fmt::Display,
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
|
||||||
macro_rules! get_variant {
|
macro_rules! get_variant {
|
||||||
|
@ -63,83 +70,90 @@ impl quote::ToTokens for CType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
named!(ctype<&str, CType>,
|
fn parse_ctype<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, CType, E> {
|
||||||
alt!(
|
(alt((
|
||||||
value!(CType::U64, complete!(tag!("ULL"))) |
|
value(CType::U64, complete(tag("ULL"))),
|
||||||
value!(CType::U32, complete!(tag!("U")))
|
value(CType::U32, complete(tag("U"))),
|
||||||
)
|
)))(i)
|
||||||
);
|
}
|
||||||
|
|
||||||
named!(cexpr<&str, (CType, String)>,
|
fn parse_cexpr<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, (CType, String), E> {
|
||||||
alt!(
|
(alt((
|
||||||
map!(cfloat, |f| (CType::Float, format!("{:.2}", f))) |
|
map(parse_cfloat, |f| (CType::Float, format!("{:.2}", f))),
|
||||||
inverse_number |
|
parse_inverse_number,
|
||||||
decimal_number |
|
parse_decimal_number,
|
||||||
hexadecimal_number
|
parse_hexadecimal_number,
|
||||||
)
|
)))(i)
|
||||||
);
|
}
|
||||||
|
|
||||||
named!(decimal_number<&str, (CType, String)>,
|
fn parse_cfloat<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, f32, E> {
|
||||||
do_parse!(
|
(terminated(nom::number::complete::float, one_of("fF")))(i)
|
||||||
num: digit1 >>
|
}
|
||||||
typ: ctype >>
|
|
||||||
((typ, num.to_string()))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
named!(hexadecimal_number<&str, (CType, String)>,
|
fn parse_inverse_number<'a, E: ParseError<&'a str>>(
|
||||||
preceded!(
|
i: &'a str,
|
||||||
alt!(tag!("0x") | tag!("0X")),
|
) -> IResult<&'a str, (CType, String), E> {
|
||||||
map!(
|
(map(
|
||||||
pair!(hex_digit1, ctype),
|
delimited(
|
||||||
|(num, typ)| (typ, format!("0x{}{}", num.to_ascii_lowercase(), typ.to_string())
|
char('('),
|
||||||
)
|
pair(
|
||||||
)
|
preceded(char('~'), parse_decimal_number),
|
||||||
)
|
opt(preceded(char('-'), digit1)),
|
||||||
);
|
|
||||||
|
|
||||||
named!(inverse_number<&str, (CType, String)>,
|
|
||||||
map!(
|
|
||||||
delimited!(
|
|
||||||
tag!("("),
|
|
||||||
pair!(
|
|
||||||
preceded!(tag!("~"), decimal_number),
|
|
||||||
opt!(preceded!(tag!("-"), digit1))
|
|
||||||
),
|
),
|
||||||
tag!(")")
|
char(')'),
|
||||||
),
|
),
|
||||||
|((ctyp, num), minus_num)| {
|
|((ctyp, num), minus_num)| {
|
||||||
let expr = if let Some(minus) = minus_num {
|
let expr = if let Some(minus) = minus_num {
|
||||||
format!("!{}-{}", num, minus)
|
format!("!{}-{}", num, minus)
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
format!("!{}", num)
|
format!("!{}", num)
|
||||||
};
|
};
|
||||||
(ctyp, expr)
|
(ctyp, expr)
|
||||||
}
|
},
|
||||||
)
|
))(i)
|
||||||
);
|
}
|
||||||
|
|
||||||
named!(cfloat<&str, f32>,
|
|
||||||
terminated!(nom::number::complete::float, one_of!("fF"))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Like a C string, but does not support quote escaping and expects at least one character.
|
// Like a C string, but does not support quote escaping and expects at least one character.
|
||||||
// If needed, use https://github.com/Geal/nom/blob/8e09f0c3029d32421b5b69fb798cef6855d0c8df/tests/json.rs#L61-L81
|
// If needed, use https://github.com/Geal/nom/blob/8e09f0c3029d32421b5b69fb798cef6855d0c8df/tests/json.rs#L61-L81
|
||||||
named!(c_include_string<&str, String>,
|
fn parse_c_include_string<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, String, E> {
|
||||||
delimited!(
|
(delimited(
|
||||||
char!('"'),
|
char('"'),
|
||||||
map!(
|
map(many1(none_of("\"")), |c| {
|
||||||
many1!(none_of!("\"")),
|
c.iter().map(char::to_string).join("")
|
||||||
|chars| chars.iter().map(char::to_string).join("")
|
}),
|
||||||
),
|
char('"'),
|
||||||
char!('"')
|
))(i)
|
||||||
)
|
}
|
||||||
);
|
|
||||||
|
|
||||||
named!(c_include<&str, String>,
|
fn parse_c_include<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, String, E> {
|
||||||
preceded!(tag!("#include"), preceded!(multispace1, c_include_string))
|
(preceded(
|
||||||
);
|
tag("#include"),
|
||||||
|
preceded(multispace1, parse_c_include_string),
|
||||||
|
))(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_decimal_number<'a, E: ParseError<&'a str>>(
|
||||||
|
i: &'a str,
|
||||||
|
) -> IResult<&'a str, (CType, String), E> {
|
||||||
|
(map(
|
||||||
|
pair(digit1.map(str::to_string), parse_ctype),
|
||||||
|
|(dig, ctype)| (ctype, dig),
|
||||||
|
))(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_hexadecimal_number<'a, E: ParseError<&'a str>>(
|
||||||
|
i: &'a str,
|
||||||
|
) -> IResult<&'a str, (CType, String), E> {
|
||||||
|
(preceded(
|
||||||
|
alt((tag("0x"), tag("0X"))),
|
||||||
|
map(pair(hex_digit1, parse_ctype), |(num, typ)| {
|
||||||
|
(
|
||||||
|
typ,
|
||||||
|
format!("0x{}{}", num.to_ascii_lowercase(), typ.to_string()),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
))(i)
|
||||||
|
}
|
||||||
|
|
||||||
fn khronos_link<S: Display + ?Sized>(name: &S) -> Literal {
|
fn khronos_link<S: Display + ?Sized>(name: &S) -> Literal {
|
||||||
Literal::string(&format!(
|
Literal::string(&format!(
|
||||||
|
@ -265,7 +279,8 @@ impl quote::ToTokens for Constant {
|
||||||
}
|
}
|
||||||
Constant::Text(ref text) => text.to_tokens(tokens),
|
Constant::Text(ref text) => text.to_tokens(tokens),
|
||||||
Constant::CExpr(ref expr) => {
|
Constant::CExpr(ref expr) => {
|
||||||
let (_, (_, rexpr)) = cexpr(expr).expect("Unable to parse cexpr");
|
let (_, (_, rexpr)) =
|
||||||
|
parse_cexpr::<VerboseError<&str>>(expr).expect("Unable to parse cexpr");
|
||||||
tokens.extend(rexpr.parse::<TokenStream>());
|
tokens.extend(rexpr.parse::<TokenStream>());
|
||||||
}
|
}
|
||||||
Constant::BitPos(pos) => {
|
Constant::BitPos(pos) => {
|
||||||
|
@ -318,7 +333,8 @@ impl Constant {
|
||||||
match self {
|
match self {
|
||||||
Constant::Number(_) | Constant::Hex(_) => CType::USize,
|
Constant::Number(_) | Constant::Hex(_) => CType::USize,
|
||||||
Constant::CExpr(expr) => {
|
Constant::CExpr(expr) => {
|
||||||
let (_, (ty, _)) = cexpr(expr).expect("Unable to parse cexpr");
|
let (_, (ty, _)) =
|
||||||
|
parse_cexpr::<VerboseError<&str>>(expr).expect("Unable to parse cexpr");
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
|
@ -549,12 +565,12 @@ fn name_to_tokens(type_name: &str) -> Ident {
|
||||||
/// Parses and rewrites a C literal into Rust
|
/// Parses and rewrites a C literal into Rust
|
||||||
///
|
///
|
||||||
/// If no special pattern is recognized the original literal is returned.
|
/// If no special pattern is recognized the original literal is returned.
|
||||||
/// Any new conversions need to be added to the [`cexpr()`] [`nom`] parser.
|
/// Any new conversions need to be added to the [`parse_cexpr()`] [`nom`] parser.
|
||||||
///
|
///
|
||||||
/// Examples:
|
/// Examples:
|
||||||
/// - `0x3FFU` -> `0x3ffu32`
|
/// - `0x3FFU` -> `0x3ffu32`
|
||||||
fn convert_c_literal(lit: Literal) -> Literal {
|
fn convert_c_literal(lit: Literal) -> Literal {
|
||||||
if let Ok((_, (_, rexpr))) = cexpr(&lit.to_string()) {
|
if let Ok((_, (_, rexpr))) = parse_cexpr::<VerboseError<&str>>(&lit.to_string()) {
|
||||||
// lit::SynInt uses the same `.parse` method to create hexadecimal
|
// lit::SynInt uses the same `.parse` method to create hexadecimal
|
||||||
// literals because there is no `Literal` constructor for it.
|
// literals because there is no `Literal` constructor for it.
|
||||||
let mut stream = rexpr.parse::<TokenStream>().unwrap().into_iter();
|
let mut stream = rexpr.parse::<TokenStream>().unwrap().into_iter();
|
||||||
|
@ -2289,7 +2305,7 @@ pub fn extract_native_types(registry: &vk_parse::Registry) -> (Vec<(String, Stri
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
|
||||||
let (rem, path) = c_include(&code.code)
|
let (rem, path) = parse_c_include::<VerboseError<&str>>(&code.code)
|
||||||
.expect("Failed to parse `#include` from `category=\"include\"` directive");
|
.expect("Failed to parse `#include` from `category=\"include\"` directive");
|
||||||
assert!(rem.is_empty());
|
assert!(rem.is_empty());
|
||||||
header_includes.push((name, path));
|
header_includes.push((name, path));
|
||||||
|
|
Loading…
Reference in a new issue