示例#1
0
        static SimpleJson()
        {
            FSharpFunc <CharStream <Unit>, Reply <JToken?> >?jvalue = null;

            var jnull = StringCI("null", (JToken?)null).Lbl("null");

            var jnum = Float.Map(i => (JToken?)i).Lbl("number");

            var jbool = StringCI("true").Or(StringCI("false"))
                        .Map(b => (JToken?)bool.Parse(b))
                        .Lbl("bool");

            var quotedString = Between('"', ManyChars(NoneOf("\"")), '"');

            var jstring = quotedString.Map(s => (JToken?)s).Lbl("string");

            var arrItems = Many(Rec(() => jvalue), sep: CharP(',').And(WS));
            var jarray   = Between(CharP('[').And(WS), arrItems, CharP(']'))
                           .Map(elems => (JToken?)new JArray(elems))
                           .Lbl("array");

            var jidentifier = quotedString.Lbl("identifier");
            var jprop       = jidentifier.And(WS).And(Skip(':')).And(WS).And(Rec(() => jvalue))
                              .Map((name, value) => new JProperty(name, value));
            var objProps = Many(jprop, sep: CharP(',').And(WS));
            var jobject  = Between(CharP('{').And(WS), objProps, CharP('}'))
                           .Map(props => (JToken?)new JObject(props))
                           .Lbl("object");

            jvalue = Choice(jnum, jbool, jnull, jstring, jarray, jobject).And(WS);

            SimpleJsonParser = WS.And(jobject).And(WS).And(EOF).Map(o => (JObject?)o);
        }
示例#2
0
        private XmlParser()
        {
            var nameStart = Choice(Letter, CharP('_'));
            var nameChar  = Choice(Letter, Digit, AnyOf("-_."));
            var name      = Many1Chars(nameStart, nameChar).And(WS);

            var quotedString = Between('"', ManyChars(NoneOf("\"")), '"');
            var attribute    = name.And(Skip('=')).And(WS).And(quotedString).And(WS)
                               .Lbl_("attribute")
                               .Map((attrName, attrVal) => new KeyValuePair <string, string>(attrName, attrVal));
            var attributes = Many(attribute);

            FSharpFunc <CharStream <Unit>, Reply <IToken> > element = null;

            var elementStart = Skip('<').AndTry(name.Lbl("tag name")).And(attributes);

            FSharpFunc <CharStream <Unit>, Reply <string> > closingTag(string tagName) => Between("</", StringP(tagName).And(WS), ">")
            .Lbl_($"closing tag '</{tagName}>'");

            FSharpFunc <CharStream <Unit>, Reply <IToken> > textContent(string leadingWS) => NotEmpty(ManyChars(NoneOf("<"))
                                                                                                      .Map(text => leadingWS + text)
                                                                                                      .Map(x => (IToken) new XmlTextToken(x))
                                                                                                      .Lbl_("text content"));

            var childElement = Rec(() => element).Lbl_("child element");

            IEnumerable <IToken> EmptyContentToEmptyString(FSharpList <IToken> xs) => xs.IsEmpty ? (IEnumerable <IToken>)ImmutableList.Create(new XmlTextToken("")) : xs;

            var elementContent = Many(WS.WithSkipped().AndTry(ws =>
                                                              Choice(textContent(ws), childElement)))
                                 .Map(EmptyContentToEmptyString);

            FSharpFunc <CharStream <Unit>, Reply <IToken> > elementEnd(string elName, FSharpList <KeyValuePair <string, string> > elAttrs) =>
            Choice(
                Skip("/>").Return(Enumerable.Empty <IToken>()),
                Skip(">").And(elementContent).And(WS).AndL(closingTag(elName)))
            .Map(elContent => (IToken) new XmlNode(elName, elAttrs.ToImmutableDictionary(), elContent.ToImmutableList()));

            element = elementStart.And(elementEnd);

            Parser = WS.And(element).And(WS).And(EOF).Map(x => x switch
            {
                XmlNode token => token,
                _ => null
            });
示例#3
0
        public Parser()
        {
            var variableP = Regex(@"\w+").Label("variable")
                            .Map(x => (IToken) new VariableToken(x));
            var numberP = Float.Label("number").Map(x => (IToken) new NumberToken(x));
            var atomicP = numberP.Or(variableP);

            FSharpFunc <CharStream <Unit>, Reply <IToken> > exprP = null;

            var assignmentP = variableP.AndLTry(WS).AndLTry(StringP("=")).AndL(WS).AndTry(Rec(() => exprP)).AndL(WS)
                              .Map((x, y) => (IToken) new AssignmentToken(((VariableToken)x).Item1, y));

            var nonRecursiveExprP = WS.And(assignmentP.Or(atomicP)).And(WS);

            var operatorP = new OPPBuilder <Unit, IToken, Unit>()
                            .WithOperators(ops => ops
                                           .AddInfix("<", 5, WS, (x, y) => new BooleanLessThan(x, y))
                                           .AddInfix("<", 5, WS, (x, y) => new BooleanLessThan(x, y))
                                           .AddInfix("<", 5, WS, (x, y) => new BooleanLessThan(x, y))
                                           .AddInfix("<", 5, WS, (x, y) => new BooleanLessThan(x, y))
                                           .AddInfix("+", 10, WS, (x, y) => new AddToken(x, y))
                                           .AddInfix("-", 10, WS, (x, y) => new DivideToken(x, y))
                                           .AddInfix("*", 20, WS, (x, y) => new MultiplyToken(x, y))
                                           .AddInfix("/", 20, WS, (x, y) => new DivideToken(x, y))
                                           .AddPrefix("-", 20, x => new NegateToken(x))
                                           .AddInfix("^", 30, Associativity.Right, WS, (x, y) => new PowerToken(x, y))
                                           .AddPostfix("!", 40, x => new FactorialToken(x))
                                           .AddTernary("?", ":", 50, Associativity.None,
                                                       (condT, ifT, elseT) => new ConditionalToken(condT, ifT, elseT))
                                           )
                            .WithImplicitOperator(20, (x, y) => new MultiplyToken(x, y))
                            .WithTerms(term => Choice(nonRecursiveExprP, Between(CharP('(').And(WS), term, CharP(')').And(WS))))
                            .Build()
                            .ExpressionParser
                            .Label("expression");

            exprP = assignmentP.Or(operatorP).Or(atomicP);

            _parser = Many(exprP, sep: WS.And(CharP(';')).And(WS), canEndWithSep: true);
        }
        public SimpleExpressionParser()
        {
            var piParser = StringP("pi").Return(Math.PI);
            var eParser  = StringP("e").Return(Math.E);

            var thing = Float.Or(piParser).Or(eParser);

            Parser =
                WS.And(new OPPBuilder <Unit, double, Unit>()
                       .WithOperators(ops => ops
                                      .AddInfix("+", 10, WS, (x, y) => x + y)
                                      .AddInfix("-", 10, WS, (x, y) => x - y)
                                      .AddInfix("*", 20, WS, (x, y) => x * y)
                                      .AddInfix("/", 20, WS, (x, y) => x / y)
                                      .AddInfix("%", 20, WS, (x, y) => x % y)
                                      .AddPrefix("-", 20, x => - x)
                                      .AddInfix("^", 30, Associativity.Right, WS, (x, y) => (int)Math.Pow(x, y))
                                      .AddPostfix("!", 40, x => Factorial(Convert.ToInt32(x))))
                       .WithTerms(term =>
            {
                var aTan  = MathFunc(term, "atan", Math.Atan);
                var aSin  = MathFunc(term, "asin", Math.Asin);
                var tan   = MathFunc(term, "tan", Math.Tan);
                var sin   = MathFunc(term, "sin", Math.Sin);
                var log   = MathFunc(term, "log", Math.Log);
                var log10 = MathFunc(term, "log10", Math.Log10);
                var ln    = MathFunc(term, "ln", x => Math.Log(x, Math.E));

                var recStuff = aTan.Or(aSin).Or(tan).Or(sin).Or(log).Or(log10).Or(ln);

                return(Choice(
                           WS.And(thing.Or(recStuff)).And(WS),
                           Between(CharP('(').And(WS), term, CharP(')').And(WS))));
            })
                       .Build()
                       .ExpressionParser);
        }
        private JsonParser()
        {
            FSharpFunc <CharStream <Unit>, Reply <JToken> > jValue = null;

            var jNull = StringCI("null", (JToken) new NullToken()).Lbl("null");

            var jNum = Float.Map(i => (JToken)i).Lbl("number");

            var jBool = StringCI("true").Or(StringCI("false"))
                        .Map(b => (JToken)bool.Parse(b))
                        .Lbl("bool");

            var quotedString = Between('"', ManyChars(NoneOf("\"")), '"');

            var jString = quotedString.Map(s => (JToken)s).Lbl("string");

            var arrItems = Many(Rec(() => jValue), CharP(',').And(WS));
            var jArray   = Between(CharP('[').And(WS), arrItems, CharP(']'))
                           .Map(elems => (JToken) new JArray(elems))
                           .Lbl("array");

            var jIdentifier = quotedString.Lbl("identifier");
            var jProp       = jIdentifier.And(WS).And(Skip(':')).And(WS).And(Rec(() => jValue))
                              .Map((name, value) => new JProperty(name, value));
            var objProps = Many(jProp, CharP(',').And(WS));
            var jObject  = Between(CharP('{').And(WS), objProps, CharP('}'))
                           .Map(props => (JToken) new JObject(props))
                           .Lbl("object");

            jValue = Choice(jNum, jBool, jNull, jString, jArray, jObject).And(WS);

            Parser = WS.And(jObject).And(WS).And(EOF).Map(o => o switch
            {
                JObject objectValue => objectValue,
                _ => null
            });