private IFormat ParseExpression(string str)
        {
            List <IFormat> operands = new List <IFormat>();
            LatexLexems    ll       = LatexLexems.getInstance();

            foreach (var def in ll.getDefinitionsLexem())
            {
                if (matches(str, def.getRegex()))
                {
                    IFormat name  = ParseExpression(getTokenValue(str, def.getRegex(), "name"));
                    IFormat value = ParseExpression(getTokenValue(str, def.getRegex(), "expr"));
                    operands.Add(name);
                    operands.Add(value);
                    return(new Latex(def.getType(), operands, null));
                }
            }

            if ((operands = ParseMultiOperandsExpression(str, '+')) != null)
            {
                return(new Latex(Types.Addition, operands, null));
            }
            if ((operands = ParseMultiOperandsExpression(str, '-')) != null)
            {
                return(new Latex(Types.Substraction, operands, null));
            }
            if ((operands = ParseMultiOperandsExpression(str, '*')) != null)
            {
                return(new Latex(Types.Multiplication, operands, null));
            }

            operands = new List <IFormat>();
            string[] strings;
            Lexem    tmp    = new Lexem(Types.Variable, "");
            int      length = 0;

            foreach (var def in ll.getOperandsLexem())
            {
                Regex rgx   = new Regex(def.getRegex());
                Match match = rgx.Match(str);
                if (match.Length > length)
                {
                    tmp    = def;
                    length = match.Length;
                }
            }
            if (tmp.getRegex() == "")
            {
                throw new Exception("Bad input, really! Follow the syntax");
            }

            switch (tmp.getType())
            {
            case Types.Variable:
                return(new Latex(str));

            case Types.Number:
                return(new Latex(Convert.ToDouble(str)));

            case Types.Interval:
            case Types.List:
            {
                str     = str.Substring(1, str.Length - 2);
                strings = str.Split(';');
                foreach (var s in strings)
                {
                    operands.Add(ParseExpression(s));
                }
                return(new Latex(tmp.getType(), operands, null));
            }

            case Types.FuncExpression:
                IFormat funcName  = ParseExpression(getTokenValue(str, tmp.getRegex(), "fr"));
                string  parametrs = getTokenValue(str, tmp.getRegex(), "sec");

                parametrs = parametrs.Substring(1, parametrs.Length - 2);
                strings   = parametrs.Split(',');
                foreach (var s in strings)
                {
                    operands.Add(ParseExpression(s));
                }
                return(new Latex(tmp.getType(), operands, funcName));
            }
            IFormat first  = ParseExpression(getTokenValue(str, tmp.getRegex(), "fr"));
            IFormat second = ParseExpression(getTokenValue(str, tmp.getRegex(), "sec"));

            operands.Add(first);
            operands.Add(second);
            return(new Latex(tmp.getType(), operands, null));
        }