1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#![allow(clippy::type_complexity)]
#![allow(clippy::module_inception)]
#![allow(clippy::nonstandard_macro_braces)]

mod ast;
mod grammar;
mod incremental_map_conformance;
mod list;
mod mutators;
mod parser;

pub use grammar::Grammar;
pub use mutators::grammar_based_string_mutator;

pub use ast::AST;
pub use mutators::ASTMutator;

/**
    Creates a grammar corresponding to a single character within the specfied range or ranges.
    ```
    use fuzzcheck::{concatenation, literal};
    let a = literal!('a'); // a single character
    let a_to_z = literal!('a' ..= 'z'); // a character within a range
    let digit_or_space = literal! { ('0'..='9'), (' ') }; // either a digit or a space
    ```
*/
#[macro_export]
macro_rules! literal {
    ($l:literal) => {
        $crate::mutators::grammar::Grammar::literal($l..=$l)
    };
    ($l:expr) => {
        $crate::mutators::grammar::Grammar::literal($l)
    };
    ( $(($x:expr)),* ) => {
        $crate::mutators::grammar::Grammar::alternation(vec![
            $(literal!($x)),*
        ])
    };
}
/**
    Creates a grammar corresponding to a sequence of rules.

    ```
    use fuzzcheck::{concatenation, literal};
    // will match only the string "abcd"
    let abcd = concatenation! {
        literal!('a'),
        literal!('b'),
        literal!('c'),
        literal!('d')
    };
    ```
*/
#[macro_export]
macro_rules! concatenation {
    ($($gsm:expr),*) => {
        $crate::mutators::grammar::Grammar::concatenation([
            $($gsm),*
        ])
    }
    ;
}

/**
    Creates a grammar corresponding to an alternation of rules.

    ```
    use fuzzcheck::{alternation, literal};
    // will match only the strings "a", "b", and "c"
    let abc = alternation! {
        literal!('a'),
        literal!('b'),
        literal!('c')
    };
    ```
*/
#[macro_export]
macro_rules! alternation {
    ($($gsm:expr),*) => {
        $crate::mutators::grammar::Grammar::alternation([
            $($gsm),*
        ])
    }
    ;
}

/**
    Creates a grammar corresponding to the repetition of a rule.

    ```
    use fuzzcheck::{repetition, literal};
    // will match only the strings "", "a", and "aa"
    let g = repetition! {
        literal!('a'),
        0 ..= 2
    };
    ```
*/
#[macro_export]
macro_rules! repetition {
    ($g:expr, $range:expr) => {
        $crate::mutators::grammar::Grammar::repetition($g, $range)
    };
}

/**
    Creates a recursive grammar.

    ```
    use fuzzcheck::{recursive, recurse, literal, alternation, concatenation};
    // will match the strings "a", "(a)", "((a))", "(((a)))", and so on
    let g = recursive! { g in
        alternation! {
            concatenation! {
                literal!('('),
                recurse!(g),
                literal!(')')
            },
            literal!('a')
        }
    };
    ```
*/
#[macro_export]
macro_rules! recursive {
    ($g:pat in $e:expr) => {
        $crate::mutators::grammar::Grammar::recursive(|$g| $e)
    };
}

/**
    Creates a point of recursion in a grammar. See: [recursive!](crate::recursive!)
*/
#[macro_export]
macro_rules! recurse {
    ($g:ident) => {
        $crate::mutators::grammar::Grammar::recurse($g)
    };
}