Macro combine::parser
[−]
[src]
macro_rules! parser { ( $(#[$attr:meta])* pub fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),* ) ($input_type: ty) -> $output_type: ty { $($parser: tt)* } ) => { ... }; ( $(#[$attr:meta])* fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),* ) ($input_type: ty) -> $output_type: ty { $($parser: tt)* } ) => { ... }; ( $(#[$attr:meta])* pub fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),* ) ($input_type: ty) -> $output_type: ty where [$($where_clause: tt)*] { $($parser: tt)* } ) => { ... }; ( $(#[$attr:meta])* fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),*) ($input_type: ty) -> $output_type: ty where [$($where_clause: tt)*] { $($parser: tt)* } ) => { ... }; ( $(#[$derive:meta])* pub struct $type_name: ident; $(#[$attr:meta])* pub fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),* ) ($input_type: ty) -> $output_type: ty where [$($where_clause: tt)*] { $($parser: tt)* } ) => { ... }; ( $(#[$derive:meta])* struct $type_name: ident; $(#[$attr:meta])* fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),*) ($input_type: ty) -> $output_type: ty where [$($where_clause: tt)*] { $($parser: tt)* } ) => { ... }; }
Declares a named parser which can easily be reused.
The expression which creates the parser should have no side effects as it may be called multiple times even during a single parse attempt.
#[macro_use] extern crate combine; use combine::char::digit; use combine::{any, choice, many1, Parser, Stream}; parser!{ fn integer[I]()(I) -> i32 where [I: Stream<Item = char>] { // The body must be a block body ( `{ <block body> }`) which ends with an expression // which evaluates to a parser let digits = many1(digit()); digits.and_then(|s: String| s.parse()) } } #[derive(Debug, PartialEq)] pub enum IntOrString { Int(i32), String(String), } // prefix with `pub` to declare a public parser parser!{ // Documentation comments works as well /// Parses an integer or a string (any characters) pub fn integer_or_string[I]()(I) -> IntOrString where [I: Stream<Item = char>] { choice!( integer().map(IntOrString::Int), many1(any()).map(IntOrString::String) ) } } parser!{ // Give the created type a unique name #[derive(Clone)] pub struct Twice; pub fn twice[F, P](f: F)(P::Input) -> (P::Output, P::Output) where [P: Parser, F: FnMut() -> P] { (f(), f()) } } fn main() { assert_eq!(integer().parse("123"), Ok((123, ""))); assert!(integer().parse("!").is_err()); assert_eq!(integer_or_string().parse("123"), Ok((IntOrString::Int(123), ""))); assert_eq!( integer_or_string().parse("abc"), Ok((IntOrString::String("abc".to_string()), "")) ); assert_eq!(twice(|| digit()).parse("123"), Ok((('1', '2'), "3"))); }