// STRING TO FORMAT PARSER
        public IFormat ParseInputToFormat(List <string> input, Types unitType, string outOptions)
        {
            LatexLexems    ll         = LatexLexems.getInstance();
            List <IFormat> unitExp    = new List <IFormat>();
            int            brackets   = 0;
            int            startIndex = 0;
            Types          type       = Types.GlobalU;
            string         options    = "";

            for (int i = 0; i < input.Count; i++)
            {
                foreach (var lex in ll.getUnitsLexem())
                {
                    if (matches(input[i], lex.getRegex()))
                    {
                        brackets++;
                        if (brackets == 1)
                        {
                            startIndex = i;
                            type       = lex.getType();
                            options    = getTokenValue(input[i], lex.getRegex(), "options");
                        }
                        break;
                    }
                }

                // Изначально в самом внешнем скопе
                if (brackets == 0)
                {
                    if (input[i] != "")
                    {
                        unitExp.Add(ParseExpression(input[i]));
                    }
                    continue;
                }

                if (matches(input[i], "}}"))
                {
                    brackets--;
                }

                if (brackets == 0) // После операции вычитания, мы вернулись в самый внешний скоп
                {
                    string[] array = new string[i - startIndex - 1];
                    input.CopyTo(startIndex + 1, array, 0, i - startIndex - 1);
                    unitExp.Add(ParseInputToFormat(array.ToList(), type, options));
                }
            }

            IFormat c = outOptions == "" ? null:ParseExpression(outOptions);

            return(new Latex(unitType, unitExp, c));
        }
        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));
        }