private SubExpression And()
        {
            SubExpression expr = Or();

            while (Peek != null)
            {
                expr = new AndExpression(new List <SubExpression> {
                    expr, Or()
                });
            }

            return(expr);
        }
        private SubExpression Factor()
        {
            Token peek = Peek;

            if (Peek is WordToken word)
            {
                SubExpression sub = null;

                foreach (char c in word.Lexeme)
                {
                    if (sub == null)
                    {
                        sub = new SingleCharacterExpression(c);
                    }
                    else
                    {
                        sub = new AndExpression(new List <SubExpression> {
                            sub, new SingleCharacterExpression(c)
                        });
                    }
                }

                Next();

                return(sub);
            }
            else if (peek.Character == '(')
            {
                Next();
                SubExpression sub = Or();
                Next(')');
                return(sub);
            }
            else if (peek.Character == '[')
            {
                Next();

                WordToken   token        = ((WordToken)Peek);
                char        rangeStart   = '\0';
                List <char> unionedRange = new List <char>();
                foreach (char c in token.Lexeme)
                {
                    if (rangeStart == '\0')
                    {
                        rangeStart = c;
                    }
                    else if (c != '-')
                    {
                        List <char> range = Ranges.First(x => x.Contains(rangeStart) && x.Contains(c));

                        for (int i = range.IndexOf(rangeStart); i < range.IndexOf(c) + 1; i++)
                        {
                            unionedRange.Add(range[i]);
                        }

                        rangeStart = '\0';
                    }
                }

                Next();
                Next(']');

                List <SubExpression> subExpressions = new List <SubExpression>();

                foreach (char c in unionedRange)
                {
                    subExpressions.Add(new SingleCharacterExpression(c));
                }

                return(new OrExpression(subExpressions));
            }
            else
            {
                SubExpression sub = new SingleCharacterExpression(peek.Character);
                Next();
                return(sub);
            }
        }