예제 #1
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
 /// <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);
예제 #5
0
 /// <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]);
예제 #6
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);
        }
예제 #8
0
 /// <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);
예제 #9
0
 /// <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);
예제 #10
0
 /// <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);
예제 #11
0
 /// <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);
예제 #12
0
 /// <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);
예제 #13
0
 /// <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);
예제 #14
0
 /// <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);
예제 #15
0
 /// <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);
예제 #16
0
 /// <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);
예제 #17
0
 /// <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);
예제 #18
0
 /// <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);
예제 #19
0
 /// <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);
예제 #20
0
 /// <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);
예제 #21
0
 /// <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);
예제 #22
0
 /// <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);
예제 #23
0
 /// <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>());
예제 #24
0
 /// <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);
예제 #25
0
 /// <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);
예제 #26
0
 /// <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);