public static void RunFluent() { var config = ParserFactory.Fluent(); var name = config.Expression(); name.ThatMatches("[a-z]+").AndReturns(f => f); var obj = config.Rule(); var attribute = config.Rule(); obj.IsMadeUp.By(name) .Followed.By("{") .Followed.ByListOf(obj).ThatIs.Optional .Followed.ByListOf(attribute).ThatIs.Optional .Followed.By("}"); attribute.IsMadeUp.By("[") .Followed.By(name) .Followed.By("=") .Followed.By(config.QuotedString).Followed.By("]"); var parser = config.CreateParser(); parser.Parse("fruits {" + " banana {" + " [tasty=\"true\"]" + " [colour=\"yellow\"]" + " }" + "" + " orange {" + " }" + " " + " [eatable=\"if not rotten\"]" + "}"); }
static Wordy() { var config = ParserFactory.Fluent(); var sentence = config.Rule(); var expr = config.Rule(); var number = config.Rule(); var op = config.Rule(); sentence.IsMadeUp.By("What is ").Followed.By(expr).As("Expression").Followed.By("?").WhenFound(f => f.Expression); expr.IsMadeUp.By(expr).As("Left").Followed.By(" ").Followed.By(op).As("Operator").Followed.By(" ").Followed.By(number).As("Right") .WhenFound(f => { switch (f.Operator) { case '+': return(f.Left + f.Right); case '-': return(f.Left - f.Right); case '*': return(f.Left * f.Right); case '/': return(f.Left / f.Right); } throw new InvalidOperationException(); }) .Or.By(number); op.IsMadeUp.By("plus").WhenFound(f => '+') .Or.By("minus").WhenFound(f => '-') .Or.By("multiplied by").WhenFound(f => '*') .Or.By("divided by").WhenFound(f => '/'); number.IsMadeUp.By <int>(); Parser = config.CreateParser(); }
static IParser <object> CreateParser() { var config = ParserFactory.Fluent(); var vv = config.Rule(); // version vector var ce = config.Rule(); // causal event var serverId = config.Expression(); serverId.ThatMatches(@"[a-z]+").AndReturns(x => x); var longValue = config.Expression(); longValue.ThatMatches(@"\d+").AndReturns(x => long.Parse(x)); ce.IsMadeUp.By("(") .Followed.By(serverId).As("i") .Followed.By(",") .Followed.By(longValue).As("n") .Followed.By(")") .WhenFound(x => new CausalEvent(x.i, x.n)); vv.IsMadeUp.By("{") .Followed.ByListOf <CausalEvent>(ce).As("events").ThatIs.SeparatedBy(",").Optional .Followed.By("}") .WhenFound(x => new VersionVector(x.events ?? Enumerable.Empty <CausalEvent>())); IParser <object> parser = config.CreateParser(); return(parser); }
public void TestFluentCalculator() { var config = ParserFactory.Fluent(); var expr = config.Rule(); var term = config.Rule(); var factor = config.Rule(); var plusOrMinus = config.Rule(); var mulOrDiv = config.Rule(); plusOrMinus.IsMadeUp.By("+").WhenFound(f => '+') .Or.By("-").WhenFound(f => '-'); expr.IsMadeUp.By(expr).As("Left").Followed.By(plusOrMinus).As("Operator").Followed.By(term).As("Right") .WhenFound(f => f.Operator == '+' ? f.Left + f.Right : f.Left - f.Right) .Or.By(term); mulOrDiv.IsMadeUp.By("*").WhenFound(f => '*') .Or.By("/").WhenFound(f => '/'); term.IsMadeUp.By(term).As("Left").Followed.By(mulOrDiv).As("Operator").Followed.By(factor).As("Right") .WhenFound(f => f.Operator == '*' ? f.Left * f.Right : f.Left / f.Right) .Or.By(factor); factor.IsMadeUp.By <int>() .Or.By("(").Followed.By(expr).As("Expression").Followed.By(")") .WhenFound(f => f.Expression); var parser = config.CreateParser(); int result = (int)parser.Parse("7+8*2-2+2"); Assert.AreEqual(23, result); }
public void TestFluentJsonParserConfiguration() { var config = ParserFactory.Fluent(); var jsonObject = config.Rule(); var jsonElement = config.Rule(); var jsonValue = config.Rule(); var jsonArray = config.Rule(); jsonObject.IsMadeUp.By("{") .Followed.ByListOf <JsonElement>(jsonElement).As("ElementList").ThatIs.SeparatedBy(",").Optional .Followed.By("}") .WhenFound(o => new JsonObject { Elements = o.ElementList }); jsonElement.IsMadeUp.By(config.QuotedString).As("Name") .Followed.By(":") .Followed.By(jsonValue).As("Value") .WhenFound(o => new JsonElement { Name = o.Name, Value = o.Value }); jsonValue.IsMadeUp.By(config.QuotedString) .Or.By <int>() .Or.By <double>() .Or.By(jsonObject) .Or.By(jsonArray) .Or.By <bool>() .Or.By("null").WhenFound(o => null); jsonArray.IsMadeUp.By("[") .Followed.ByListOf(jsonValue).As("Values").ThatIs.SeparatedBy(",").Optional .Followed.By("]") .WhenFound(o => o.Values); var parser = config.CreateParser(); var jObject = (JsonObject)parser.Parse( @"{ ""Property1"":""va\""lue"", ""IntegerProperty"" : 1234, ""array"":[1,2,3,4,5], ""another_object"" : { ""another_property"":13.37 }, ""empty_object"" : { } }"); Assert.AreEqual(5, jObject.Elements.Count); }
public void TestIgnoreExpression() { var config = ParserFactory.Fluent(); var rule = config.Rule(); rule.IsMadeUp.By("a").Followed.By("b"); config.Ignore("c"); var parser = config.CreateParser(); parser.Parse("acccccccccccccccbccccccccccccccccc"); }
public void TestTokenAssociativity() { var config = ParserFactory.Fluent(); config.LeftAssociative("+", "-"); config.LeftAssociative("*", "/"); var expr = config.Rule(); expr.IsMadeUp.By(expr).Followed.By("+").Followed.By(expr) .Or.By(expr).Followed.By("-").Followed.By(expr) .Or.By(expr).Followed.By("*").Followed.By(expr) .Or.By(expr).Followed.By("/").Followed.By(expr) .Or.By("(").Followed.By("-").Followed.By(")") .Or.By <int>(); }
public void TestErrorRecoveryInFluentConfiguration() { int caughtErrors = 0; var configurator = ParserFactory.Fluent(); var listOfA = configurator.Rule(); var a = configurator.Rule(); var terminatedA = configurator.Rule(); a.IsMadeUp.By(a).As("Init").Followed.By("a").WhenFound(f => f.Init + 1) .Or.By("a").WhenFound(f => 1); terminatedA.IsMadeUp.By(a).As("A").Followed.By(";").WhenFound(f => f.A) .Or.By(configurator.Error).Followed.By(";").WhenFound(f => { Console.WriteLine(f.Error); ++caughtErrors; return(0); }); listOfA.IsMadeUp.By(terminatedA).As("A").WhenFound(f => f.A) .Or.By(listOfA).As("A").Followed.By(terminatedA).As("TA").WhenFound(f => f.A + f.TA); // Bogus terminal that isn't in any sort of use var b = configurator.Expression(); b.ThatMatches("b").AndReturns(f => null); var parser = configurator.CreateParser(); const string legal = "aaaaaaa;aaaaaaaaaa;aaa;aa;a;aaaaa;aaaaaaaa;"; var legalAs = (int)parser.Parse(legal); Assert.AreEqual(legal.Aggregate(0, (i, c) => c == 'a' ? i + 1 : i), legalAs); Assert.AreEqual(0, caughtErrors); const string withErrors = "aaaaaaa;aaaaaabaaa;aaa;aa;a;aaaaa;aaaaaaaa;"; legalAs = (int)parser.Parse(withErrors); Assert.AreEqual("aaaaaaa;THESEAREEATEN;aaa;aa;a;aaaaa;aaaaaaaa;".Aggregate(0, (i, c) => c == 'a' ? i + 1 : i), legalAs); Assert.AreEqual(1, caughtErrors); }