public void CompleteInventoryRequestOrder_ParserMethod() { var log = new List <string>(); // ParserMethods.CreateManualInventoryOrder("ZZZ - Dummy", 10); var fields = new NameValueCollection(); fields.Add("Task Name", "(10/20) ZZZ - Dummy"); ParserMethods.CompleteInventoryRequestOrder(fields, ref log, true); }
public void CharacterString_Test() { var parser = ParserMethods.CharacterString("abc"); var input = new StringCharacterSequence("abcd"); var result = parser.Parse(input); result.Success.Should().BeTrue(); result.Value.Should().Be("abc"); result.Consumed.Should().Be(3); }
public void ShipOrderParser() { var log = new List <string>(); NameValueCollection fields = new NameValueCollection(); fields.Add("Order ID", "1878"); fields.Add("Shipping Cost", "0.00"); var returnVal = ParserMethods.ProcessShippedProductOrder(ref log, fields, false); }
/// <summary> /// Transform the values of all result alternatives. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TMiddle"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="multiParser"></param> /// <param name="transform"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> Transform <TInput, TMiddle, TOutput>(this IMultiParser <TInput, TMiddle> multiParser, Func <TMiddle, TOutput> transform) => ParserMethods <TInput> .Transform(multiParser, transform);
/// <summary> /// Zero-length assertion that the given parser's result is followed by another sequence. /// The lookahead sequence is matched but not consumed. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <param name="lookahead"></param> /// <returns></returns> public static IParser <TInput, TOutput> FollowedBy <TInput, TOutput>(this IParser <TInput, TOutput> p, IParser <TInput> lookahead) => ParserMethods <TInput> .Combine(p, ParserMethods <TInput> .PositiveLookahead(lookahead)).Transform(r => (TOutput)r[0]);
/// <summary> /// Cache the output of the given parser so that the next call to .Parse at the same /// location will return the existing result. Useful when the parser is particularly /// expensive to execute and likely to be executed multiple times. /// </summary> /// <typeparam name="TInput"></typeparam> /// <param name="p"></param> /// <returns></returns> public static IParser <TInput> Cache <TInput>(this IParser <TInput> p) => ParserMethods <TInput> .Cache(p);
public int Calculate(string s) { var ws = Whitespace(); var ows = OptionalWhitespace(); var integer = Rule( DigitString(), ows, (d, ws) => new RpnToken(d, RpnTokenType.Number) ); var operators = Rule( First( Match('+'), Match('-'), Match('*'), Match('/') ), OptionalWhitespace(), (op, ws) => new RpnToken(op.ToString(), RpnTokenType.Operator) ); var tokens = First( integer, operators, If(End(), Produce(() => new RpnToken("", RpnTokenType.End))) ); var tokenSequence = tokens .ToSequence(new StringCharacterSequence(s)) .Select(r => r.GetValueOrDefault(() => new RpnToken(r.ErrorMessage, RpnTokenType.Failure))); var parser = ParserMethods <RpnToken> .Function <int>(args => { var startingLocation = args.Input.CurrentLocation; var stack = new Stack <int>(); while (!args.Input.IsAtEnd) { var token = args.Input.GetNext(); if (token == null) { return(args.Failure("Received null token")); } if (token.Type == RpnTokenType.Failure) { return(args.Failure("Tokenization error: " + token.Value)); } if (token.Type == RpnTokenType.End) { break; } if (token.Type == RpnTokenType.Number) { stack.Push(int.Parse(token.Value)); continue; } if (token.Type == RpnTokenType.Operator) { var b = stack.Pop(); var a = stack.Pop(); switch (token.Value) { case "+": stack.Push(a + b); break; case "-": stack.Push(a - b); break; case "*": stack.Push(a *b); break; case "/": stack.Push(a / b); break; } } } if (stack.Count != 1) { return(args.Failure("Invalid sequence, expected to have 1 token remaining")); } return(args.Success(stack.Pop())); }); var result = parser.Parse(tokenSequence); if (!result.Success) { throw new Exception("Parse failed"); } return(result.Value); }
/// <summary> /// Push a recursive data frame before executing the given parser, and then pop the data /// frame when the parser completes. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> WithDataContext <TInput, TOutput>(this IMultiParser <TInput, TOutput> p) => ParserMethods <TInput> .DataContext(p);
/// <summary> /// The result value of the parser is stored as contextual state data in the parse state. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <typeparam name="TValue"></typeparam> /// <param name="p"></param> /// <param name="name"></param> /// <param name="getValue"></param> /// <returns></returns> public static IParser <TInput, TOutput> SetResultData <TInput, TOutput, TValue>(this IParser <TInput, TOutput> p, string name, Func <TOutput, TValue> getValue) => ParserMethods <TInput> .SetResultData(p, name, getValue);
/// <summary> /// The results of the given parser are optional. Returns success with an Option value /// which can be used to determine if the parser succeeded. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <returns></returns> public static IParser <TInput, IOption <TOutput> > Optional <TInput, TOutput>(this IParser <TInput, TOutput> p) => ParserMethods <TInput> .Optional(p);
/// <summary> /// Wraps the given parser to guarantee that it consumes no input. /// </summary> /// <typeparam name="TInput"></typeparam> /// <param name="inner"></param> /// <returns></returns> public static IParser <TInput> None <TInput>(this IParser <TInput> inner) => ParserMethods <TInput> .None(inner);
/// <summary> /// Transform the output of the given parser. Synonym for Transform. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TMiddle"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="parser"></param> /// <param name="transform"></param> /// <returns></returns> public static IParser <TInput, TOutput> Map <TInput, TMiddle, TOutput>(this IParser <TInput, TMiddle> parser, Func <TMiddle, TOutput> transform) => ParserMethods <TInput> .Transform(parser, transform);
/// <summary> /// Returns a list of results from the given parser separated by a separator /// pattern. Continues until the item or separator pattern return failure, or /// the minimum/maximum counts are not satisfied. Returns an enumeration of results. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TSeparator"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <param name="separator"></param> /// <param name="minimum"></param> /// <param name="maximum"></param> /// <returns></returns> public static IParser <TInput, IReadOnlyList <TOutput> > ListSeparatedBy <TInput, TSeparator, TOutput>(this IParser <TInput, TOutput> p, IParser <TInput, TSeparator> separator, int minimum = 0, int?maximum = null) => ParserMethods <TInput> .SeparatedList(p, separator, minimum, maximum);
/// <summary> /// Returns a list of results from the given parser separated by a separator pattern. Continues until /// the item or separator parser return failure. Returns an enumerable of results. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TSeparator"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <param name="separator"></param> /// <param name="atLeastOne"></param> /// <returns></returns> public static IParser <TInput, IReadOnlyList <TOutput> > ListSeparatedBy <TInput, TSeparator, TOutput>(this IParser <TInput, TOutput> p, IParser <TInput, TSeparator> separator, bool atLeastOne) => ParserMethods <TInput> .SeparatedList(p, separator, atLeastOne);
/// <summary> /// Transform the values of all result alternatives. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TMiddle"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="multiParser"></param> /// <param name="transform"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> Transform <TInput, TMiddle, TOutput>(this IMultiParser <TInput, TMiddle> multiParser, Func <Transform <TInput, TMiddle, TOutput> .MultiArguments, IMultiResult <TOutput> > transform) => ParserMethods <TInput> .TransformResultMulti(multiParser, transform);
/// <summary> /// The results of the given parser are optional. If the given parser fails, a default value /// will be returned. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <param name="getDefault"></param> /// <returns></returns> public static IParser <TInput, TOutput> Optional <TInput, TOutput>(this IParser <TInput, TOutput> p, Func <IParseState <TInput>, TOutput> getDefault) => ParserMethods <TInput> .Optional(p, getDefault);
/// <summary> /// The result value of the parser is stored as contextual state data in the parse state. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <param name="name"></param> /// <returns></returns> public static IParser <TInput, TOutput> SetResultData <TInput, TOutput>(this IParser <TInput, TOutput> p, string name) => ParserMethods <TInput> .SetResultData(p, name);
/// <summary> /// Make this parser replaceable. /// </summary> /// <typeparam name="TInput"></typeparam> /// <param name="p"></param> /// <returns></returns> public static IParser <TInput> Replaceable <TInput>(this IParser <TInput> p) => ParserMethods <TInput> .Replaceable(p);
/// <summary> /// Push a recursive data frame before executing the given parser, and then pop the data /// frame when the parser completes. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <typeparam name="TData"></typeparam> /// <param name="p"></param> /// <param name="values"></param> /// <returns></returns> public static IParser <TInput, TOutput> WithDataContext <TInput, TOutput, TData>(this IParser <TInput, TOutput> p, Dictionary <string, TData> values) => ParserMethods <TInput> .DataContext(p, values);
/// <summary> /// Make this parser replaceable. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> Replaceable <TInput, TOutput>(this IMultiParser <TInput, TOutput> p) => ParserMethods <TInput> .Replaceable(p);
/// <summary> /// Push a recursive data frame before executing the given parser, and then pop the data /// frame when the parser completes. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <typeparam name="TData"></typeparam> /// <param name="p"></param> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> WithDataContext <TInput, TOutput, TData>(this IMultiParser <TInput, TOutput> p, string name, TData value) where TData : notnull => ParserMethods <TInput> .DataContext(p, name, value);
/// <summary> /// Make this parser replaceable. Gives the parser a name so that it can be easily found /// and replaced. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <param name="name"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> Replaceable <TInput, TOutput>(this IMultiParser <TInput, TOutput> p, string name) => ParserMethods <TInput> .Replaceable(p).Named(name);
/// <summary> /// Attempt to parse with a predicate parser. If the predicate parser succeeds, /// parse with the given parser. This is the same operation as If with different order of operands. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="predicate"></param> /// <param name="parser"></param> /// <returns></returns> public static IParser <TInput, TOutput> Then <TInput, TOutput>(this IParser <TInput> predicate, IParser <TInput, TOutput> parser) => new IfParser <TInput, TOutput>(predicate, parser, ParserMethods <TInput> .Fail <TOutput>());
/// <summary> /// Transform the complete result object of the given parser. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TMiddle"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="parser"></param> /// <param name="transform"></param> /// <returns></returns> public static IParser <TInput, TOutput> TransformResult <TInput, TMiddle, TOutput>(this IParser <TInput, TMiddle> parser, Func <Transform <TInput, TMiddle, TOutput> .SingleArguments, IResult <TOutput> > transform) => ParserMethods <TInput> .TransformResult(parser, transform);
/// <summary> /// Cache result values of this parser so on the next call to Parse from the same location /// an existing result value can be used. /// </summary> /// <typeparam name="TInput"></typeparam> /// <typeparam name="TOutput"></typeparam> /// <param name="p"></param> /// <returns></returns> public static IMultiParser <TInput, TOutput> Cache <TInput, TOutput>(this IMultiParser <TInput, TOutput> p) => ParserMethods <TInput> .Cache(p);
/// <summary> /// Convenience method to match a literal sequence of characters and return the /// result as a string. /// </summary> /// <param name="pattern"></param> /// <returns></returns> public static IParser <char, string> CharacterString(string pattern) => ParserMethods <char> .Match(pattern).Transform(c => pattern);