private static void Initialize() { if (_initialized) { return; } _initialized = true; _lexer = new Lexer(); _lexer.AddIgnore(@"\s+"); var suffix = _lexer.Add("²|³|°", "SUFFIX"); var prefix = _lexer.Add(@"√|∛|abs|acos|arg|asin|atan|cbrt|cnj|cosh?|deg|exp|im|ln|rad|rcp|re|sinh?|sqrt|tanh?", "PREFIX"); var prefix2 = _lexer.Add(@"log_|root_", "PREFIX2"); var infix0 = _lexer.Add(@"\^", "INFIX0"); var infix1 = _lexer.Add(@"[*/×÷∠]", "INFIX1"); var infix2 = _lexer.Add(@"[--++]", "INFIX2"); var number = _lexer.Add(@"[0-9]+([.][0-9]*)?i?|[.][0-9]+i?|i", "NUMBER"); var open = _lexer.Add(@"\(", "("); var close = _lexer.Add(@"\)", ")"); var variable = _lexer.Add(@"x", "x"); var constant = _lexer.Add(@"[eπ|pi]", "CONST"); var expr = Patterns.Choice <Expression>("expr"); var factor1 = Patterns.Choice( number.Map(t => Expression.Constant(ParseComplex(t.Text))), constant.Map(t => Expression.Constant(GetConst(t.Text))), variable.Map(t => (Expression)X), Patterns.Seq(open, expr, close, (_, x, __) => x), Patterns.Seq(open, expr, (_, x) => x, "")); var factor2 = Patterns.Choice <Expression>("factor"); factor2.AddRange( factor1, Patterns.Seq(factor2, suffix, (x, t) => Invoke(GetUnary(t.Text), x), "", Priority.Left(20)), Patterns.Seq(factor2, infix0, factor2, (x, t, y) => Invoke(GetBinary(t.Text), x, y), "", Priority.Right(19))); var term2 = Patterns.Choice <Expression>("term2"); var term1 = Patterns.Choice <Expression>("term1"); term1.AddRange(factor2, Patterns.Seq(factor2, term1, (left, right) => Expression.Multiply(left, right), "", Priority.Right(15)), Patterns.Seq(prefix, term2, (t, x) => Invoke(GetUnary(t.Text), x), "", Priority.Right(15)), Patterns.Seq(prefix, suffix, term2, (t, u, x) => Invoke(GetUnary(u.Text), Invoke(GetUnary(t.Text), x)), "", Priority.Right(15)), Patterns.Seq(prefix, infix0, factor2, term2, (t, u, y, x) => Invoke(GetBinary(u.Text), Invoke(GetUnary(t.Text), x), y), "", Priority.Right(15)), Patterns.Seq(prefix2, factor2, term2, (t, y, x) => Invoke(GetBinary(t.Text), x, y), "", Priority.Right(15))); term2.AddRange(term1, Patterns.Seq(infix2, term2, (t, x) => Invoke(GetUnary(t.Text), x), "", Priority.Right(15))); expr.AddRange( term2, Patterns.Seq(expr, infix1, expr, (x, t, y) => Invoke(GetBinary(t.Text), x, y), "", Priority.Left(9)), Patterns.Seq(expr, infix2, expr, (x, t, y) => Invoke(GetBinary(t.Text), x, y), "", Priority.Left(8))); _parser = expr.CreateParser(); }