using System;
using System.Collections.Immutable;
namespace Parsing {
public static class ParserCombinator {
///
/// Parser then Parser = Parser
/// ( => R1 ) then ( => R2 ) is ( => Tuple[R2, R1] )
///
public static IParser> Then(this IParser firstParser, IParser secondParser) =>
new ParserThenParser(firstParser, secondParser);
///
/// Parser then Consumer = Parser
/// ( => R ) then ( => ) is ( => R )
///
public static IParser Then(this IParser parser, IConsumer consumer) =>
new ParserThenConsumer(parser, consumer);
///
/// Parser then Transformer = Parser
/// ( => R1 ) then ( R1 => R2 ) is ( => R2 )
///
public static IParser Then(this IParser parser, ITransformer transformer) =>
new ParserThenTransformer(parser, transformer);
public static IParser Then(this IParser parser, Func transformer) =>
parser.Then(new SimpleTransformer(transformer));
public static IParser Then(this IParser> parser, Func transformer) =>
parser.Then(_ => transformer(_.Item2, _.Item1));
public static IParser Then(this IParser>> parser, Func transformer) =>
parser.Then(_ => transformer(_.Item2.Item2, _.Item2.Item1, _.Item1));
public static IParser Then(this IParser>>> parser, Func transformer) =>
parser.Then(_ => transformer(_.Item2.Item2.Item2, _.Item2.Item2.Item1, _.Item2.Item1, _.Item1));
///
/// Consumer then Parser = Parser
/// ( => ) then ( => R ) is ( => R )
///
public static IParser Then(this IConsumer consumer, IParser parser) =>
new ConsumerThenParser(consumer, parser);
///
/// Consumer then Consumer = Consumer
/// ( => ) then ( => ) is ( => )
///
public static IConsumer Then(this IConsumer firstConsumer, IConsumer secondConsumer) =>
new ConsumerThenConsumer(firstConsumer, secondConsumer);
///
/// Transformer then Parser = Transformer
/// ( S => R1 ) then ( => R2 ) is ( S => Tuple[R2, R1] )
///
public static ITransformer> Then(this ITransformer transformer, IParser parser) =>
new TransformerThenParser(transformer, parser);
///
/// Transformer then Consumer = Transformer
/// ( S => R ) then ( => ) is ( S => R )
///
public static ITransformer Then(this ITransformer transformer, IConsumer consumer) =>
new TransformerThenConsumer(transformer, consumer);
///
/// Transformer then Transformer = Transformer
/// ( S => I ) then ( I => R ) is ( S => R )
///
public static ITransformer Then(this ITransformer firstTransformer, ITransformer secondTransformer) =>
new TransformerThenTransformer(firstTransformer, secondTransformer);
public static ITransformer Then(this ITransformer firstTransformer, Func secondTransformer) =>
firstTransformer.Then(new SimpleTransformer(secondTransformer));
public static ITransformer Then(this ITransformer> firstTransformer, Func secondTransformer) =>
firstTransformer.Then(_ => secondTransformer(_.Item2, _.Item1));
public static ITransformer Then(this ITransformer>> firstTransformer, Func secondTransformer) =>
firstTransformer.Then(_ => secondTransformer(_.Item2.Item2, _.Item2.Item1, _.Item1));
///
/// Create an optional parser.
///
public static IParser