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> Optional(this IParser parser) => new OptionalParser(parser); public static IParser Optional(this IParser parser, R defaultValue) => new OptionalParserWithDefault(parser, defaultValue); public static OrConsumer Either(IConsumer consumer) => new OrConsumer(ImmutableList.Create(consumer)); public static OrConsumer Or(ImmutableList firstConsumer, IConsumer secondConsumer) => new OrConsumer(firstConsumer.Add(secondConsumer)); /// /// Consumer or Consumer /// //public static IConsumer Or(this IConsumer firstConsumer, IConsumer secondConsumer) => // new ConsumerOrConsumer(firstConsumer, secondConsumer); /// /// ( => R ) check Predicate[IParserResult[R]] is ( => R) /// public static IParser Check(this IParser parser, Predicate> predicate) => new ParserThenCheck(parser, predicate); public static IParser TransformResult(this IParser parser, Func, IParserResult> transformFunc) => Then(parser, new ResultTransformer(transformFunc)); public static IParser TransformEnvironment(this IParser parser, Func transformFunc) => parser.Then(new EnvironmentTransformer(transformFunc)); public static IConsumer TransformEnvironment(this IConsumer consumer, Func transformFunc) => consumer.Then(new EnvironmentTransformer(transformFunc)); public static ITransformer Optional(this ITransformer transformer) => new OptionalTransformer(transformer); public static OrTransformer Either(ITransformer transformer) => new OrTransformer(ImmutableList.Create(transformer)); public static OrTransformer Or(this OrTransformer firstTransformer, ITransformer secondTransformer) => new OrTransformer(firstTransformer.Transformers.Add(secondTransformer)); //public static ITransformer Or(this ITransformer firstTransformer, ITransformer secondTransformer) => // new TransformerOrTransformer(firstTransformer, secondTransformer); //public static IParser Or(this IParser firstParser, IParser secondParser) => // new ParserOrParser(firstParser, secondParser); public static OrParser Either(IParser parser) => new OrParser(ImmutableList.Create(parser)); public static OrParser Or(this OrParser firstParser, IParser secondParser) => new OrParser(firstParser.Parsers.Add(secondParser)); public static IParser Optional(this IConsumer consumer) => new OptionalConsumer(consumer); public static ITransformer ZeroOrMore(this ITransformer transformer) => new ZeroOrMoreTransformer(transformer); public static ITransformer OneOrMore(this ITransformer transformer) => new OneOrMoreTransformer(transformer); public static IParser> ZeroOrMore(this IParser parser) => new ZeroOrMoreParser(parser); public static IParser> OneOrMore(this IParser parser) => new OneOrMoreParser(parser); public static IParser> OneOrMoreForEntireUnit(this IParser parser) => new OneOrMoreParserForEntireUnit(parser); public static IParser> OneOrMore(this IParser elementParser, IConsumer separatorConsumer) => new OneOrMoreParserWithSeparator(separatorConsumer, elementParser); public static ITransformer Given() => new IdentityTransformer(); public static ITransformer, Tuple> Given() => Given>(); } }