1# How nom macros work 2 3**NOTE: macros were removed in nom 7. You should now use the function based combinators** 4 5nom uses Rust macros heavily to provide a nice syntax and generate parsing code. 6This has multiple advantages: 7 8* It gives the appearance of combining functions without the runtime cost of closures 9* It helps Rust's code inference and borrow checking (less lifetime issues than iterator based solutions) 10* The generated code is very linear, just a large chain of pattern matching 11 12As a prerequisite, if you need more information on macros, please refer to 13[the little book of Rust macros](https://danielkeep.github.io/tlborm/book/README.html) 14and the [Macromancy talk](https://www.youtube.com/watch?v=8rodUyaGkQo) 15 16# Defining a new macro 17 18Let's take the `opt!` macro as example: `opt!` returns `IResult<I,Option<O>>`, 19producing a `Some(o)` if the child parser succeeded, and None otherwise. Here 20is how you could use it: 21 22```rust 23named!(opt_tag<Option<&[u8]>>, opt!(digit)); 24``` 25 26And here is how it is defined: 27 28```rust 29#[macro_export] 30macro_rules! opt( 31 ($i:expr, $submac:ident!( $($args:tt)* )) => ({ 32 match $submac!($i, $($args)*) { 33 Ok((i,o)) => Ok((i, Some(o))), 34 Err(Err::Error(_)) => Ok(($i, None)), 35 Err(e) => Err(e), 36 } 37 }); 38 ($i:expr, $f:expr) => ( 39 opt!($i, call!($f)); 40 ); 41); 42``` 43 44To define a Rust macro, you indicate the name of the macro, then each pattern it 45is meant to apply to: 46 47```rust 48macro_rules! my_macro ( 49 (<pattern1>) => ( <generated code for pattern1> ); 50 (<pattern2>) => ( <generated code for pattern2> ); 51); 52``` 53 54## Passing input 55 56The first thing you can see in `opt!` is that the pattern have an additional 57parameter that you do not use: 58 59```rust 60($i:expr, $f:expr) 61``` 62 63While you call: 64 65```rust 66opt!(digit) 67``` 68 69This is the first trick of nom macros: the first parameter, usually `$i` or `$input`, 70is the input data, passed by the parent parser. The expression using `named!` will 71translate like this: 72 73```rust 74named!(opt_tag<Option<&[u8]>>, opt!(digit)); 75``` 76 77to 78 79```rust 80fn opt_tag(input:&[u8]) -> IResult<&[u8], Option<&[u8]>> { 81 opt!(input, digit) 82} 83``` 84 85This is how combinators hide all the plumbing: they receive the input automatically 86from the parent parser, may use that input, and pass the remaining input to the child 87parser. 88 89When you have multiple submacros, such as this example, the input is always passed 90to the first, top level combinator: 91 92```rust 93macro_rules! multispaced ( 94 ($i:expr, $submac:ident!( $($args:tt)* )) => ( 95 delimited!($i, opt!(multispace), $submac!($($args)*), opt!(multispace)); 96 ); 97 ($i:expr, $f:expr) => ( 98 multispaced!($i, call!($f)); 99 ); 100); 101``` 102 103Here, `delimited!` will apply `opt!(multispace)` on the input, and if successful, 104will apply `$submac!($($args)*)` on the remaining input, and if successful, store 105the output and apply `opt!(multispace)` on the remaining input. 106 107## Applying on macros or functions 108 109The second trick you can see is the two patterns: 110 111```rust 112#[macro_export] 113macro_rules! opt( 114 ($i:expr, $submac:ident!( $($args:tt)* )) => ( 115 [...] 116 ); 117 ($i:expr, $f:expr) => ( 118 opt!($i, call!($f)); 119 ); 120); 121``` 122 123The first pattern is used to receive a macro as child parser, like this: 124 125```rust 126opt!(tag!("abcd")) 127``` 128 129The second pattern can receive a function, and transforms it in a macro, then calls 130itself again. This is done to avoid repeating code. Applying `opt!` with `digit` 131as argument would be transformed from this: 132 133```rust 134opt!(digit) 135``` 136 137transformed with the second pattern: 138 139```rust 140opt!(call!(digit)) 141``` 142 143The `call!` macro transforms `call!(input, f)` into `f(input)`. If you need to pass 144more parameters to the function, you can Use `call!(input, f, arg, arg2)` to get 145`f(input, arg, arg2)`. 146 147## Using the macro's parameters 148 149The macro argument is decomposed into `$submac:ident!`, the macro's name and a bang, 150and `( $($args:tt)* )`, the tokens contained between the parenthesis of the macro call. 151 152```rust 153($i:expr, $submac:ident!( $($args:tt)* )) => ({ 154 match $submac!($i, $($args)*) { 155 Ok((i,o)) => Ok((i, Some(o))), 156 Err(Err::Error(_)) => Ok(($i, None)), 157 Err(e) => Err(e), 158 } 159 }); 160``` 161 162The macro is called with the input we got, as first argument, then we pattern 163match on the result. Every combinator or parser must return a `IResult`, which 164is a `Result<(I, O), nom::Err<I, E>>`, so you know which patterns you need to 165verify. If you need to call two parsers in a sequence, use the first parameter 166of `Ok((i,o))`: It is the input remaining after the first parser was applied. 167 168As an example, see how the `preceded!` macro works: 169 170```rust 171($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => ( 172 { 173 match $submac!($i, $($args)*) { 174 Err(e) => Err(e), 175 Ok((i1, _)) => { 176 $submac2!(i1, $($args2)*) 177 }, 178 } 179 } 180 ); 181``` 182 183It applies the first parser, and if it succeeds, discards its result, and applies 184the remaining input `i1` to the second parser. 185