Skip to content

Instantly share code, notes, and snippets.

Created August 5, 2017 10:35
Show Gist options
  • Save anonymous/e8b7ea953b4877a02d06b0082f85a5f4 to your computer and use it in GitHub Desktop.
Save anonymous/e8b7ea953b4877a02d06b0082f85a5f4 to your computer and use it in GitHub Desktop.
Rust code shared from the playground
pub struct Or<A, B>(A, B);
impl<A, B> Parser for Or<A, B> where A: Parser, B: Parser<Input = A::Input, Output = A::Output> {
type Input = A::Input;
type Output = A::Input;
}
impl<'a, T> Parser for &'a mut T where T: Parser {
type Input = T::Input;
type Output = T::Input;
}
pub trait ChoiceParser {
type Input;
type Output;
fn parse_choice(&mut self, input: Self::Input);
}
pub trait Parser {
type Input;
type Output;
fn parse_lazy(&mut self, input: Self::Input) {
}
fn or<P2>(self, p: P2) -> Or<Self, P2>
where
Self: Sized,
P2: Parser<Input = Self::Input, Output = Self::Output>,
{
panic!();
}
}
#[macro_export]
macro_rules! choice {
($first : expr) => {
$first
};
($first : expr, $($rest : expr),+) => {
$first.or(choice!($($rest),+))
}
}
macro_rules! tuple_choice_parser {
($head: ident) => {
};
($head: ident $($id: ident)+) => {
tuple_choice_parser_inner!($head $($id)+);
tuple_choice_parser!($($id)+);
};
}
macro_rules! tuple_choice_parser_inner {
($($id: ident)+) => {
#[allow(non_snake_case)]
impl<Input, Output $(,$id)+> ChoiceParser for ($($id),+)
where
$($id: Parser<Input = Input, Output = Output>),+
{
type Input = Input;
type Output = Output;
#[inline]
fn parse_choice(&mut self, input: Self::Input) {
let ($(ref mut $id),+) = *self;
choice!($($id),+).parse_lazy(input)
}
}
}
}
tuple_choice_parser!(A B C D E F G H I J K L M N O P Q R S T U V X Y Z);
fn main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment