/
Parser.Then.cs
87 lines (84 loc) · 4.54 KB
/
Parser.Then.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using System;
namespace Pidgin
{
public abstract partial class Parser<TToken, T>
{
/// <summary>
/// Creates a parser which applies the current parser followed by a specified parser.
/// The resulting parser returns the result of the second parser, ignoring the result of the current parser.
/// </summary>
/// <typeparam name="U">The return type of the second parser</typeparam>
/// <param name="parser">A parser to apply after applying the current parser</param>
/// <returns>A parser which applies the current parser followed by <paramref name="parser"/></returns>
public Parser<TToken, U> Then<U>(Parser<TToken, U> parser)
{
if (parser == null)
{
throw new ArgumentNullException(nameof(parser));
}
return Then(parser, (t, u) => u);
}
/// <summary>
/// Creates a parser which applies the current parser followed by a specified parser, applying a function to the two results.
/// </summary>
/// <remarks>
/// This is a synonym for <see cref="Parser.Map{TToken, T1, T2, R}(Func{T1, T2, R}, Parser{TToken, T1}, Parser{TToken, T2})"/>
/// with the arguments rearranged.
/// </remarks>
/// <typeparam name="U">The return type of the second parser</typeparam>
/// <typeparam name="R">The return type of the composed parser</typeparam>
/// <param name="parser">A parser to apply after applying the current parser</param>
/// <param name="result">A function to apply to the two parsed values</param>
/// <returns>A parser which applies the current parser followed by <paramref name="parser"/></returns>
public Parser<TToken, R> Then<U, R>(Parser<TToken, U> parser, Func<T, U, R> result)
{
if (parser == null)
{
throw new ArgumentNullException(nameof(parser));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
return Parser.Map(result, this, parser);
}
/// <summary>
/// Creates a parser that applies a transformation function to the return value of the current parser.
/// The transformation function dynamically chooses a second parser, which is applied after applying the current parser.
/// </summary>
/// <remarks>This function is a synonym for <see cref="Parser{TToken, T}.Bind{U}(Func{T, Parser{TToken, U}})"/></remarks>
/// <param name="selector">A transformation function which returns a parser to apply after applying the current parser</param>
/// <typeparam name="U">The type of the return value of the second parser</typeparam>
/// <returns>A parser which applies the current parser before applying the result of the <paramref name="selector"/> function.</returns>
public Parser<TToken, U> Then<U>(Func<T, Parser<TToken, U>> selector)
{
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}
return Bind(selector);
}
/// <summary>
/// Creates a parser that applies a transformation function to the return value of the current parser.
/// The transformation function dynamically chooses a second parser, which is applied after applying the current parser.
/// </summary>
/// <remarks>This function is a synonym for <see cref="Parser{TToken, T}.Bind{U, R}(Func{T, Parser{TToken, U}}, Func{T, U, R})"/></remarks>
/// <param name="selector">A transformation function which returns a parser to apply after applying the current parser</param>
/// <param name="result">A function to apply to the return values of the two parsers</param>
/// <typeparam name="U">The type of the return value of the second parser</typeparam>
/// <typeparam name="R">The type of the return value of the resulting parser</typeparam>
/// <returns>A parser which applies the current parser before applying the result of the <paramref name="selector"/> function</returns>
public Parser<TToken, R> Then<U, R>(Func<T, Parser<TToken, U>> selector, Func<T, U, R> result)
{
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
return Bind(selector, result);
}
}
}