@@ -395,19 +395,19 @@ public static TokenListParser<TKind, T[]> Many<TKind, T>(this TokenListParser<TK
395
395
return input =>
396
396
{
397
397
var result = new List < T > ( ) ;
398
- var @ from = input ;
398
+ var from = input ;
399
399
var r = parser ( input ) ;
400
400
while ( r . HasValue )
401
401
{
402
- if ( @ from == r . Remainder ) // Broken parser, not a failed parsing.
403
- throw new ParseException ( $ "Many() cannot be applied to zero-width parsers; value { r . Value } at position { r . Location . Position } .") ;
402
+ if ( from == r . Remainder ) // Broken parser, not a failed parsing.
403
+ throw new ParseException ( $ "Many() cannot be applied to zero-width parsers; value { r . Value } at position { r . Location . Position } .", r . ErrorPosition ) ;
404
404
405
405
result . Add ( r . Value ) ;
406
- @ from = r . Remainder ;
406
+ from = r . Remainder ;
407
407
r = parser ( r . Remainder ) ;
408
408
}
409
409
410
- if ( ! r . Backtrack && r . IsPartial ( @ from) )
410
+ if ( ! r . Backtrack && r . IsPartial ( from ) )
411
411
return TokenListParserResult . CastEmpty < TKind , T , T [ ] > ( r ) ;
412
412
413
413
return TokenListParserResult . Value ( result . ToArray ( ) , input , from ) ;
@@ -433,7 +433,7 @@ public static TextParser<T[]> Many<T>(this TextParser<T> parser)
433
433
while ( r . HasValue )
434
434
{
435
435
if ( from == r . Remainder ) // Broken parser, not a failed parsing.
436
- throw new ParseException ( $ "Many() cannot be applied to zero-width parsers; value { r . Value } at position { r . Location . Position } .") ;
436
+ throw new ParseException ( $ "Many() cannot be applied to zero-width parsers; value { r . Value } at position { r . Location . Position } .", r . Location . Position ) ;
437
437
438
438
result . Add ( r . Value ) ;
439
439
@@ -467,7 +467,7 @@ public static TextParser<Unit> IgnoreMany<T>(this TextParser<T> parser)
467
467
while ( r . HasValue )
468
468
{
469
469
if ( from == r . Remainder ) // Broken parser, not a failed parsing.
470
- throw new ParseException ( $ "IgnoreMany() cannot be applied to zero-width parsers; value { r . Value } at position { r . Location . Position } .") ;
470
+ throw new ParseException ( $ "IgnoreMany() cannot be applied to zero-width parsers; value { r . Value } at position { r . Location . Position } .", r . Location . Position ) ;
471
471
472
472
from = r . Remainder ;
473
473
r = parser ( r . Remainder ) ;
@@ -499,6 +499,8 @@ public static TokenListParser<TKind, T[]> ManyDelimitedBy<TKind, T, U>(
499
499
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
500
500
if ( delimiter == null ) throw new ArgumentNullException ( nameof ( delimiter ) ) ;
501
501
502
+ // ReSharper disable once ConvertClosureToMethodGroup
503
+
502
504
if ( end != null )
503
505
return parser
504
506
. AtLeastOnceDelimitedBy ( delimiter )
@@ -655,7 +657,7 @@ public static TextParser<T> Named<T>(this TextParser<T> parser, string name)
655
657
/// <param name="parser">The parser.</param>
656
658
/// <param name="defaultValue">The default value</param>
657
659
/// <returns>The resulting parser.</returns>
658
- public static TokenListParser < TKind , T > OptionalOrDefault < TKind , T > ( this TokenListParser < TKind , T > parser , T defaultValue = default ( T ) )
660
+ public static TokenListParser < TKind , T > OptionalOrDefault < TKind , T > ( this TokenListParser < TKind , T > parser , T defaultValue = default )
659
661
{
660
662
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
661
663
@@ -670,7 +672,7 @@ public static TextParser<T> Named<T>(this TextParser<T> parser, string name)
670
672
/// <param name="parser">The parser.</param>
671
673
/// <param name="defaultValue">The default value.</param>
672
674
/// <returns>The resulting parser.</returns>
673
- public static TextParser < T > OptionalOrDefault < T > ( this TextParser < T > parser , T defaultValue = default ( T ) )
675
+ public static TextParser < T > OptionalOrDefault < T > ( this TextParser < T > parser , T defaultValue = default )
674
676
{
675
677
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
676
678
@@ -746,7 +748,16 @@ public static TokenListParser<TKind, U> Select<TKind, T, U>(this TokenListParser
746
748
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
747
749
if ( selector == null ) throw new ArgumentNullException ( nameof ( selector ) ) ;
748
750
749
- return parser . Then ( rt => Parse . Return < TKind , U > ( selector ( rt ) ) ) ;
751
+ return input =>
752
+ {
753
+ var rt = parser ( input ) ;
754
+ if ( ! rt . HasValue )
755
+ return TokenListParserResult . CastEmpty < TKind , T , U > ( rt ) ;
756
+
757
+ var u = selector ( rt . Value ) ;
758
+
759
+ return TokenListParserResult . Value ( u , input , rt . Remainder ) ;
760
+ } ;
750
761
}
751
762
752
763
/// <summary>
@@ -762,7 +773,16 @@ public static TextParser<U> Select<T, U>(this TextParser<T> parser, Func<T, U> s
762
773
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
763
774
if ( selector == null ) throw new ArgumentNullException ( nameof ( selector ) ) ;
764
775
765
- return parser . Then ( rt => Parse . Return ( selector ( rt ) ) ) ;
776
+ return input =>
777
+ {
778
+ var rt = parser ( input ) ;
779
+ if ( ! rt . HasValue )
780
+ return Result . CastEmpty < T , U > ( rt ) ;
781
+
782
+ var u = selector ( rt . Value ) ;
783
+
784
+ return Result . Value ( u , input , rt . Remainder ) ;
785
+ } ;
766
786
}
767
787
768
788
/// <summary>
@@ -778,7 +798,7 @@ public static TokenListParser<TKind, U> Cast<TKind, T, U>(this TokenListParser<T
778
798
{
779
799
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
780
800
781
- return parser . Then ( rt => Parse . Return < TKind , U > ( ( U ) rt ) ) ;
801
+ return parser . Select ( rt => ( U ) rt ) ;
782
802
}
783
803
784
804
/// <summary>
@@ -793,7 +813,7 @@ public static TextParser<U> Cast<T, U>(this TextParser<T> parser)
793
813
{
794
814
if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
795
815
796
- return parser . Then ( rt => Parse . Return ( ( U ) rt ) ) ;
816
+ return parser . Select ( rt => ( U ) rt ) ;
797
817
}
798
818
799
819
/// <summary>
@@ -1023,6 +1043,113 @@ public static TextParser<T> Where<T>(this TextParser<T> parser, Func<T, bool> pr
1023
1043
1024
1044
return Result . Empty < T > ( input , "unsatisfied condition" ) ;
1025
1045
} ;
1046
+ }
1047
+
1048
+ /// <summary>
1049
+ /// Parse a sequence of operands connected by left-associative operators.
1050
+ /// </summary>
1051
+ /// <typeparam name="TResult">The type of the leftmost operand and of the ultimate result.</typeparam>
1052
+ /// <typeparam name="TOperator">The type of the operator.</typeparam>
1053
+ /// <typeparam name="TOperand">The type of subsequent operands.</typeparam>
1054
+ /// <param name="parser">The parser for the leftmost operand.</param>
1055
+ /// <param name="operator">A parser matching operators.</param>
1056
+ /// <param name="operand">A parser matching operands.</param>
1057
+ /// <param name="apply">A function combining the operator, left operand, and right operand, into the result.</param>
1058
+ /// <returns>The result of calling <paramref name="apply"/> successively on pairs of operands.</returns>
1059
+ public static TextParser < TResult > Chain < TResult , TOperator , TOperand > (
1060
+ this TextParser < TResult > parser ,
1061
+ TextParser < TOperator > @operator ,
1062
+ TextParser < TOperand > operand ,
1063
+ Func < TOperator , TResult , TOperand , TResult > apply )
1064
+ {
1065
+ if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
1066
+ if ( @operator == null ) throw new ArgumentNullException ( nameof ( @operator ) ) ;
1067
+ if ( operand == null ) throw new ArgumentNullException ( nameof ( operand ) ) ;
1068
+ if ( apply == null ) throw new ArgumentNullException ( nameof ( apply ) ) ;
1069
+
1070
+ return input =>
1071
+ {
1072
+ var parseResult = parser ( input ) ;
1073
+ if ( ! parseResult . HasValue )
1074
+ return parseResult ;
1075
+
1076
+ var result = parseResult . Value ;
1077
+ var operandRemainder = parseResult . Remainder ;
1078
+
1079
+ var operatorResult = @operator ( operandRemainder ) ;
1080
+ while ( operatorResult . HasValue || operatorResult . IsPartial ( operandRemainder ) )
1081
+ {
1082
+ // If operator read any input, but failed to read complete input, we return error
1083
+ if ( ! operatorResult . HasValue )
1084
+ return Result . CastEmpty < TOperator , TResult > ( operatorResult ) ;
1085
+
1086
+ var operandResult = operand ( operatorResult . Remainder ) ;
1087
+ operandRemainder = operandResult . Remainder ;
1088
+
1089
+ if ( ! operandResult . HasValue )
1090
+ return Result . CastEmpty < TOperand , TResult > ( operandResult ) ;
1091
+
1092
+ result = apply ( operatorResult . Value , result , operandResult . Value ) ;
1093
+
1094
+ operatorResult = @operator ( operandRemainder ) ;
1095
+ }
1096
+
1097
+ return Result . Value ( result , input , operandRemainder ) ;
1098
+ } ;
1099
+ }
1100
+
1101
+ /// <summary>
1102
+ /// Parse a sequence of operands connected by left-associative operators.
1103
+ /// </summary>
1104
+ /// <typeparam name="TKind">The kind of the tokens being parsed.</typeparam>
1105
+ /// <typeparam name="TResult">The type of the leftmost operand and of the ultimate result.</typeparam>
1106
+ /// <typeparam name="TOperator">The type of the operator.</typeparam>
1107
+ /// <typeparam name="TOperand">The type of subsequent operands.</typeparam>
1108
+ /// <param name="parser">The parser for the leftmost operand.</param>
1109
+ /// <param name="operator">A parser matching operators.</param>
1110
+ /// <param name="operand">A parser matching operands.</param>
1111
+ /// <param name="apply">A function combining the operator, left operand, and right operand, into the result.</param>
1112
+ /// <returns>The result of calling <paramref name="apply"/> successively on pairs of operands.</returns>
1113
+ public static TokenListParser < TKind , TResult > Chain < TKind , TResult , TOperator , TOperand > (
1114
+ this TokenListParser < TKind , TResult > parser ,
1115
+ TokenListParser < TKind , TOperator > @operator ,
1116
+ TokenListParser < TKind , TOperand > operand ,
1117
+ Func < TOperator , TResult , TOperand , TResult > apply )
1118
+ {
1119
+ if ( parser == null ) throw new ArgumentNullException ( nameof ( parser ) ) ;
1120
+ if ( @operator == null ) throw new ArgumentNullException ( nameof ( @operator ) ) ;
1121
+ if ( operand == null ) throw new ArgumentNullException ( nameof ( operand ) ) ;
1122
+ if ( apply == null ) throw new ArgumentNullException ( nameof ( apply ) ) ;
1123
+
1124
+ return input =>
1125
+ {
1126
+ var parseResult = parser ( input ) ;
1127
+ if ( ! parseResult . HasValue )
1128
+ return parseResult ;
1129
+
1130
+ var result = parseResult . Value ;
1131
+ var operandRemainder = parseResult . Remainder ;
1132
+
1133
+ var operatorResult = @operator ( operandRemainder ) ;
1134
+ while ( operatorResult . HasValue || operatorResult . IsPartial ( operandRemainder ) )
1135
+ {
1136
+ // If operator read any input, but failed to read complete input, we return error
1137
+ if ( ! operatorResult . HasValue )
1138
+ return TokenListParserResult . CastEmpty < TKind , TOperator , TResult > ( operatorResult ) ;
1139
+
1140
+ var operandResult = operand ( operatorResult . Remainder ) ;
1141
+ operandRemainder = operandResult . Remainder ;
1142
+
1143
+ if ( ! operandResult . HasValue )
1144
+ return TokenListParserResult . CastEmpty < TKind , TOperand , TResult > ( operandResult ) ;
1145
+
1146
+ result = apply ( operatorResult . Value , result , operandResult . Value ) ;
1147
+
1148
+ operatorResult = @operator ( operandRemainder ) ;
1149
+ }
1150
+
1151
+ return TokenListParserResult . Value ( result , input , operandRemainder ) ;
1152
+ } ;
1026
1153
}
1027
1154
}
1028
1155
}
0 commit comments