Skip to content

Commit

Permalink
Merge #513
Browse files Browse the repository at this point in the history
513: Make pest_generator / pest_derive no_std compatible. r=CAD97 a=01mf02

This is the follow-up pull request to #498.
It adds "std" feature flags for both pest_generator and pest_derive.
Currently, the correct function of this can only be tested by running `cargo test --no-default-features` *in the `derive` directory*.
Running `cargo test --no-default-features` in the root directory unfortunately does not run the tests in no_std mode.

Co-authored-by: Michael Färber <michael.faerber@gedenkt.at>
Co-authored-by: Michael Färber <01mf02@gmail.com>
  • Loading branch information
3 people committed Oct 10, 2021
2 parents 9acced9 + 338373c commit bc0dd1b
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 19 deletions.
8 changes: 6 additions & 2 deletions derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ readme = "_README.md"
name = "pest_derive"
proc-macro = true

[features]
default = ["std"]
std = ["pest/std", "pest_generator/std"]

[dependencies]
# for tests, included transitively anyway
pest = { path = "../pest", version = "2.1.0" }
pest_generator = { path = "../generator", version = "2.1.0" }
pest = { path = "../pest", version = "2.1.0", default-features = false }
pest_generator = { path = "../generator", version = "2.1.0", default-features = false }

[badges]
codecov = { repository = "pest-parser/pest" }
Expand Down
3 changes: 3 additions & 0 deletions derive/tests/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
#![allow(unknown_lints, clippy)]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::{format, vec::Vec};

#[macro_use]
extern crate pest;
Expand Down
4 changes: 4 additions & 0 deletions derive/tests/grammar_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::{format, vec::Vec};

#[macro_use]
extern crate pest;
#[macro_use]
Expand Down
4 changes: 4 additions & 0 deletions derive/tests/lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::{format, vec::Vec};

#[macro_use]
extern crate pest;
#[macro_use]
Expand Down
4 changes: 4 additions & 0 deletions derive/tests/reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::vec;

#[macro_use]
extern crate pest;
#[macro_use]
Expand Down
8 changes: 6 additions & 2 deletions generator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_generator"
description = "pest code generator"
version = "2.1.3"
version = "2.1.4"
authors = ["Dragoș Tiselice <dragostiselice@gmail.com>"]
homepage = "https://pest-parser.github.io/"
repository = "https://github.com/pest-parser/pest"
Expand All @@ -11,8 +11,12 @@ categories = ["parsing"]
license = "MIT/Apache-2.0"
readme = "_README.md"

[features]
default = ["std"]
std = ["pest/std"]

[dependencies]
pest = { path = "../pest", version = "2.1.0" }
pest = { path = "../pest", version = "2.1.0", default-features = false }
pest_meta = { path = "../meta", version = "2.1.0" }
proc-macro2 = "1.0"
quote = "1.0"
Expand Down
59 changes: 46 additions & 13 deletions generator/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@ pub fn generate(

let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

let result = result_type();

let parser_impl = quote! {
#[allow(clippy::all)]
impl #impl_generics ::pest::Parser<Rule> for #name #ty_generics #where_clause {
fn parse<'i>(
rule: Rule,
input: &'i str
) -> ::std::result::Result<
) -> #result<
::pest::iterators::Pairs<'i, Rule>,
::pest::error::Error<Rule>
> {
Expand Down Expand Up @@ -148,13 +150,15 @@ fn generate_builtin_rules() -> Vec<(&'static str, TokenStream)> {
.or_else(|state| state.match_string("\r"))
);

let box_ty = box_type();

for property in UNICODE_PROPERTY_NAMES {
let property_ident: Ident = syn::parse_str(property).unwrap();
// insert manually for #property substitution
builtins.push((property, quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
fn #property_ident(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
fn #property_ident(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.match_char_by(::pest::unicode::#property_ident)
}
}));
Expand Down Expand Up @@ -233,11 +237,13 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
generate_expr(rule.expr)
};

let box_ty = box_type();

match rule.ty {
RuleType::Normal => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.rule(Rule::#name, |state| {
#expr
})
Expand All @@ -246,14 +252,14 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
RuleType::Silent => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
#expr
}
},
RuleType::Atomic => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.rule(Rule::#name, |state| {
state.atomic(::pest::Atomicity::Atomic, |state| {
#expr
Expand All @@ -264,7 +270,7 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
RuleType::CompoundAtomic => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.atomic(::pest::Atomicity::CompoundAtomic, |state| {
state.rule(Rule::#name, |state| {
#expr
Expand All @@ -275,7 +281,7 @@ fn generate_rule(rule: OptimizedRule) -> TokenStream {
RuleType::NonAtomic => quote! {
#[inline]
#[allow(non_snake_case, unused_variables)]
pub fn #name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn #name(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.atomic(::pest::Atomicity::NonAtomic, |state| {
state.rule(Rule::#name, |state| {
#expr
Expand Down Expand Up @@ -613,13 +619,38 @@ struct QuoteOption<T>(Option<T>);

impl<T: ToTokens> ToTokens for QuoteOption<T> {
fn to_tokens(&self, tokens: &mut TokenStream) {
let option = option_type();
tokens.append_all(match self.0 {
Some(ref t) => quote! { ::std::option::Option::Some(#t) },
None => quote! { ::std::option::Option::None },
Some(ref t) => quote! { #option::Some(#t) },
None => quote! { #option::None },
});
}
}

fn box_type() -> TokenStream {
#[cfg(feature = "std")]
quote! { ::std::boxed::Box }

#[cfg(not(feature = "std"))]
quote! { ::alloc::boxed::Box }
}

fn result_type() -> TokenStream {
#[cfg(feature = "std")]
quote! { ::std::result::Result }

#[cfg(not(feature = "std"))]
quote! { ::core::result::Result }
}

fn option_type() -> TokenStream {
#[cfg(feature = "std")]
quote! { ::std::option::Option }

#[cfg(not(feature = "std"))]
quote! { ::core::option::Option }
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -929,6 +960,8 @@ mod tests {
expr: OptimizedExpr::Str("b".to_owned()),
}];
let defaults = vec!["ANY"];
let result = result_type();
let box_ty = box_type();
assert_eq!(
generate(name, &generics, Some(String::from("test.pest")), rules, defaults, true).to_string(),
quote! {
Expand All @@ -946,7 +979,7 @@ mod tests {
fn parse<'i>(
rule: Rule,
input: &'i str
) -> ::std::result::Result<
) -> #result<
::pest::iterators::Pairs<'i, Rule>,
::pest::error::Error<Rule>
> {
Expand All @@ -957,7 +990,7 @@ mod tests {

#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
pub fn skip(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn skip(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
Ok(state)
}
}
Expand All @@ -967,13 +1000,13 @@ mod tests {

#[inline]
#[allow(non_snake_case, unused_variables)]
pub fn a(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn a(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.match_string("b")
}

#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
pub fn ANY(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn ANY(state: #box_ty<::pest::ParserState<Rule>>) -> ::pest::ParseResult<#box_ty<::pest::ParserState<Rule>>> {
state.skip(1)
}
}
Expand Down
32 changes: 30 additions & 2 deletions generator/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,52 @@ macro_rules! insert_public_builtin {
};
}

#[cfg(feature = "std")]
macro_rules! generate_rule {
($name: ident, $pattern: expr) => {
quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
pub fn $name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn $name(state: ::std::boxed::Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState<Rule>>> {
$pattern
}
}
}
}

#[cfg(not(feature = "std"))]
macro_rules! generate_rule {
($name: ident, $pattern: expr) => {
quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
pub fn $name(state: ::alloc::boxed::Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<::alloc::boxed::Box<::pest::ParserState<Rule>>> {
$pattern
}
}
}
}

#[cfg(feature = "std")]
macro_rules! generate_public_rule {
($name: ident, $pattern: expr) => {
quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
pub fn $name(state: ::std::boxed::Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<::std::boxed::Box<::pest::ParserState<Rule>>> {
$pattern
}
}
}
}

#[cfg(not(feature = "std"))]
macro_rules! generate_public_rule {
($name: ident, $pattern: expr) => {
quote! {
#[inline]
#[allow(dead_code, non_snake_case, unused_variables)]
pub fn $name(state: Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<Box<::pest::ParserState<Rule>>> {
pub fn $name(state: ::alloc::boxed::Box<::pest::ParserState<Rule>>) -> ::pest::ParseResult<::alloc::boxed::Box<::pest::ParserState<Rule>>> {
$pattern
}
}
Expand Down

0 comments on commit bc0dd1b

Please sign in to comment.