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); }
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 });
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 });