src/main/java/br/com/starcode/parccser/Parser.java
protected NegationSelector negation(int number) throws ParserException {

        StringBuilder sb = new StringBuilder();
        ignoreWhitespaces();
        if (end() || current != '(') {
            throw new ParserException("Expected '(' at position " + pos);
        }
        //sb.append(current);
        int parenthesisPos = pos;
        next();
        ignoreWhitespaces();
        if (end()) {
            throw new ParserException("Selector expected at position " + pos);
        }
        int initialPos = pos;
        SimpleSelector simpleSelector = null;
        if (current == '*') {
            //universal selector
            sb.append(current);
            TypeSelector ts = new TypeSelector("*", new Context(content, "*", initialPos, pos + 1));
            parserListener.negationTypeSelector(ts);
            simpleSelector = ts;
            next();
        } else if (Character.isLetter(current)) {
            //type selector
            String type = identifier();
            sb.append(type);
            TypeSelector ts = new TypeSelector(type, new Context(content, type, initialPos, pos));
            parserListener.negationTypeSelector(ts);
            simpleSelector = ts;
        } else if (current == '.') {
            //class selector
            sb.append(current);
            next();
            String className = !end() ? identifier() : null;
            if (className == null || className.isEmpty()) {
                throw new ParserException("Expected className at position " + pos);
            }
            ClassSelector cs = new ClassSelector(className, new Context(content, "." + className, initialPos, pos));
            simpleSelector = cs;
            parserListener.negationClassSelector(cs);
            sb.append(className);
        } else if (current == '#') {
            //hash selector
            sb.append(current);
            next();
            String id = !end() ? identifier() : null;
            if (id == null || id.isEmpty()) {
                throw new ParserException("Expected id at position " + pos);
            }
            HashSelector hs = new HashSelector(id, new Context(content, "#" + id, initialPos, pos));
            simpleSelector = hs;
            parserListener.negationIdSelector(hs);
            sb.append(id);
        } else if (current == '[') {
            //attribute selectors
            sb.append(current);
            next();
            AttributeSelector as = attribute();
            simpleSelector = as;
            parserListener.negationAttributeSelector(as);
            sb.append(as.getContext());
            sb.append(']');
        } else if (current == ':') {
            //pseudo-class only
            sb.append(current);
            next();
            if (end()) {
                throw new ParserException("Expected pseudo-element or pseudo-class at " + pos);
            }
            boolean doubleColon = false;
            if (current == ':') {
                doubleColon = true;
                sb.append(current);
                next();
            }
            String ident = !end() ? identifier() : null;
            if (ident == null || ident.isEmpty()) {
                throw new ParserException("Expected identifier at position " + pos);
            }
            if ("not".equalsIgnoreCase(ident) || isPseudoSpecialCase(ident) || doubleColon) {
                throw new ParserException("Expected pseudo-class (starting with ':', except ':not', ':first-line', ':first-letter', ':before' and ':after') at position " + pos);
            }
            PseudoSelector ps = pseudo(ident, PseudoType.PSEUDO_CLASS, doubleColon);
            simpleSelector = ps;
            parserListener.negationPseudoSelector(ps);
            sb.append(ps.getContext());
        } else {
            throw new ParserException("Selector expected at position " + pos);
        }

        ignoreWhitespaces();
        if (end() || current != ')') {
            throw new ParserException("Expected ')' at position " + pos);
        }
        //sb.append(current);
        next();

        return new NegationSelector(simpleSelector, new Context(content, sb.toString(), parenthesisPos, pos));

    }
protected NegationSelector negation(int number) throws ParserException {

        StringBuilder sb = new StringBuilder();
        ignoreWhitespaces();
        if (end() || current != '(') {
            throw new ParserException("Expected '(' at position " + pos);
        }
        //sb.append(current);
        int parenthesisPos = pos;
        next();
        ignoreWhitespaces();
        if (end()) {
            throw new ParserException("Selector expected at position " + pos);
        }
        int initialPos = pos;
        SimpleSelector simpleSelector = null;
        if (current == '*') {
            //universal selector
            sb.append(current);
            TypeSelector ts = new TypeSelector("*", new Context(content, "*", initialPos, pos + 1));
            parserListener.negationTypeSelector(ts);
            simpleSelector = ts;
            next();
        } else if (Character.isLetter(current)) {
            //type selector
            String type = identifier();
            sb.append(type);
            TypeSelector ts = new TypeSelector(type, new Context(content, type, initialPos, pos));
            parserListener.negationTypeSelector(ts);
            simpleSelector = ts;
        } else if (current == '.') {
            //class selector
            sb.append(current);
            next();
            String className = !end() ? identifier() : null;
            if (className == null || className.isEmpty()) {
                throw new ParserException("Expected className at position " + pos);
            }
            ClassSelector cs = new ClassSelector(className, new Context(content, "." + className, initialPos, pos));
            simpleSelector = cs;
            parserListener.negationClassSelector(cs);
            sb.append(className);
        } else if (current == '#') {
            //hash selector
            sb.append(current);
            next();
            String id = !end() ? identifier() : null;
            if (id == null || id.isEmpty()) {
                throw new ParserException("Expected id at position " + pos);
            }
            HashSelector hs = new HashSelector(id, new Context(content, "#" + id, initialPos, pos));
            simpleSelector = hs;
            parserListener.negationIdSelector(hs);
            sb.append(id);
        } else if (current == '[') {
            //attribute selectors
            sb.append(current);
            next();
            AttributeSelector as = attribute();
            simpleSelector = as;
            parserListener.negationAttributeSelector(as);
            sb.append(as.getContext());
            sb.append(']');
        } else if (current == ':') {
            //pseudo-class only
            sb.append(current);
            next();
            if (end()) {
                throw new ParserException("Expected pseudo-element or pseudo-class at " + pos);
            }
            boolean doubleColon = false;
            if (current == ':') {
                doubleColon = true;
                sb.append(current);
                next();
            }
            String ident = !end() ? identifier() : null;
            if (ident == null || ident.isEmpty()) {
                throw new ParserException("Expected identifier at position " + pos);
            }
            if ("not".equalsIgnoreCase(ident) || isPseudoSpecialCase(ident) || doubleColon) {
                throw new ParserException("Expected pseudo-class (starting with ':', except ':not', ':first-line', ':first-letter', ':before' and ':after') at position " + pos);
            }
            PseudoSelector ps = pseudo(ident, PseudoType.PSEUDO_CLASS, doubleColon);
            simpleSelector = ps;
            parserListener.negationPseudoSelector(ps);
            sb.append(ps.getContext());
        } else {
            throw new ParserException("Selector expected at position " + pos);
        }

        ignoreWhitespaces();
        if (end() || current != ')') {
            throw new ParserException("Expected ')' at position " + pos);
        }
        //sb.append(current);
        next();

        return new NegationSelector(simpleSelector, new Context(content, sb.toString(), parenthesisPos, pos));

    }
negation
: NOT S* negation_arg S* ')'

negation_arg
: type_selector | universal | HASH | class | attrib | pseudo

TODO include "not" or not? It would be necessary to use parameters