private Selector parseSelector() {
        Pair<List<SimpleSelector>, PseudoElementSelector> simpleSelectors = parseSimpleSelectors();
        CompoundSelector compoundSelector = CompoundSelector.of(simpleSelectors.first);
        PseudoElementSelector pseudoElement = simpleSelectors.second;
        while (pseudoElement == null) {
            Pair<Token, Boolean> p = skipWhitespace();
            if (p.first.type == TokenType.EOF) {
                break;
            } else if (p.first.type == TokenType.COMMA) {
                savedToken = p.first;
                break;
            }

            Combinator combinator = null;
            if (p.first.type == TokenType.DELIM) {
                switch (p.first.value) {
                case ">":
                    combinator = Combinator.CHILD;
                    break;
                case "+":
                    combinator = Combinator.NEXT_SIBLING;
                    break;
                case "~":
                    combinator = Combinator.LATER_SIBLING;
                    break;
                }
            }

            if (combinator == null) {
                if (p.second) {
                    combinator = Combinator.DESCENDANT;
                } else {
                    throw expected("one of ' ', '>', '+', '~'", p.first);
                }

                savedToken = p.first;
            }

            simpleSelectors = parseSimpleSelectors();
            compoundSelector = new CompoundSelector(simpleSelectors.first, new Pair<>(combinator, compoundSelector));
        }

        return new Selector(compoundSelector, pseudoElement);
    }