static void PartTwo(string[] input) { var basicExprParser = new OPPBuilder <Unit, long, Unit>() .WithOperators(ops => ops .AddInfix("+", 2, (x, y) => x + y) .AddInfix("*", 1, (x, y) => x * y)) .WithTerms(term => Choice(Long, Between('(', term, ')'))) .Build() .ExpressionParser; foreach (var line in input) { var expr = line.Replace(" ", string.Empty); var res = basicExprParser.Run(expr).GetResult(); p2 += res; } }
public static void Solve() { var ih = InputHelper.LoadInputP(2020); var lns = ih.AsLines(); { var basicExprParser = new OPPBuilder <Unit, long, Unit>() .WithOperators(ops => ops .AddInfix("+", 1, (x, y) => x + y) .AddInfix("*", 1, (x, y) => x * y)) .WithTerms(term => Choice(Long, Between('(', term, ')'))) .Build() .ExpressionParser; long sum = 0; foreach (var ln in lns) { var ln2 = ln.Replace(" ", ""); var calculated = basicExprParser.Run(ln2).GetResult(); sum += calculated; } var res1 = sum; } { var basicExprParser = new OPPBuilder <Unit, long, Unit>() .WithOperators(ops => ops .AddInfix("+", 2, (x, y) => x + y) .AddInfix("*", 1, (x, y) => x * y)) .WithTerms(term => Choice(Long, Between('(', term, ')'))) .Build() .ExpressionParser; long sum = 0; foreach (var ln in lns) { var ln2 = ln.Replace(" ", ""); var calculated = basicExprParser.Run(ln2).GetResult(); sum += calculated; } var res2 = sum; } }
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 static void Parse2() { { // best way to get result var x = Many1(Digit).AndR(Upper).Run("123a"); //// throws exception //var rx = x.GetResult(); } { // get as string var y = Many1(Digit).AndR(Many1(Upper)).Run("123A"); Microsoft.FSharp.Collections.FSharpList <char> ry1 = y.GetResult(); var ry2 = new string(ry1.ToArray()); } { var x = Many1(Digit).AndR(Upper).Run("123a"); // does not throw var rx = x.UnwrapResult(); } // arithmetic expressions { var basicExprParser = new OPPBuilder <Unit, int, Unit>() .WithOperators(ops => ops .AddInfix("+", 1, (x, y) => x + y) .AddInfix("*", 2, (x, y) => x * y)) .WithTerms(Natural) .Build() .ExpressionParser; var recursiveExprParser = new OPPBuilder <Unit, int, Unit>() .WithOperators(ops => ops .AddInfix("+", 1, (x, y) => x + y) .AddInfix("*", 2, (x, y) => x * y)) .WithTerms(term => Choice(Natural, Between('(', term, ')'))) .Build() .ExpressionParser; var calculated = recursiveExprParser.Run("4*(2+3*2)").GetResult(); } // save expr tree as graph { var naturalTermToBasicElt = Natural.Map(i => new BasicValue { Val = i } as IBasicElt); var basicExprParser = new OPPBuilder <Unit, IBasicElt, Unit>() .WithOperators(ops => ops .AddInfix("+", 1, (x, y) => new BasicExprTree("PLUS", x, y)) .AddInfix("*", 2, (x, y) => new BasicExprTree("TIMES", x, y))) //.WithTerms(Natural.Map(i => new BasicValue { Val = i } as IBasicElt)) .WithTerms(naturalTermToBasicElt) .Build() .ExpressionParser ; var recursiveExprParser = new OPPBuilder <Unit, IBasicElt, Unit>() .WithOperators(ops => ops .AddInfix("+", 1, (x, y) => new BasicExprTree("PLUS", x, y)) .AddInfix("*", 2, (x, y) => new BasicExprTree("TIMES", x, y))) .WithTerms(term => Choice(naturalTermToBasicElt, Between('(', term, ')'))) .Build() .ExpressionParser; var calculated = recursiveExprParser.Run("4*(2+3*2)").GetResult(); var calculatedVal = calculated.Calculate(); } }