function (untilTokens) {
                var i, e, done, value, 
                    tok = untilTokens || ';',
                    index = parserInput.i, result = [];

                function testCurrentChar() {
                    var char = parserInput.currentChar();
                    if (typeof tok === 'string') {
                        return char === tok;
                    } else {
                        return tok.test(char);
                    }
                }
                if (testCurrentChar()) {
                    return;
                }
                value = [];
                do {
                    e = this.comment();
                    if (e) {
                        value.push(e);
                        continue;
                    }
                    e = this.entity();
                    if (e) {
                        value.push(e);
                    }
                } while (e);

                done = testCurrentChar();
                
                if (value.length > 0) {
                    value = new(tree.Expression)(value);
                    if (done) {
                        return value;
                    }
                    else {
                        result.push(value);
                    }
                    // Preserve space before $parseUntil as it will not
                    if (parserInput.prevChar() === ' ') {
                        result.push(new tree.Anonymous(' ', index));
                    }
                }
                parserInput.save();
                
                value = parserInput.$parseUntil(tok);

                if (value) {
                    if (typeof value === 'string') {
                        error('Expected \'' + value + '\'', 'Parse');
                    }
                    if (value.length === 1 && value[0] === ' ') {
                        parserInput.forget();
                        return new tree.Anonymous('', index);
                    }
                    var item;
                    for (i = 0; i < value.length; i++) {
                        item = value[i];
                        if (Array.isArray(item)) {
                            // Treat actual quotes as normal quoted values
                            result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));
                        }
                        else {
                            if (i === value.length - 1) {
                                item = item.trim();
                            }
                            // Treat like quoted values, but replace vars like unquoted expressions
                            var quote = new tree.Quoted('\'', item, true, index, fileInfo);
                            quote.variableRegex = /@([\w-]+)/g;
                            quote.propRegex = /\$([\w-]+)/g;
                            result.push(quote);
                        }
                    }
                    parserInput.forget();
                    return new tree.Expression(result, true);
                }
                parserInput.restore();
            }
function (untilTokens) {
                var i, e, done, value, 
                    tok = untilTokens || ';',
                    index = parserInput.i, result = [];

                function testCurrentChar() {
                    var char = parserInput.currentChar();
                    if (typeof tok === 'string') {
                        return char === tok;
                    } else {
                        return tok.test(char);
                    }
                }
                if (testCurrentChar()) {
                    return;
                }
                value = [];
                do {
                    e = this.comment();
                    if (e) {
                        value.push(e);
                        continue;
                    }
                    e = this.entity();
                    if (e) {
                        value.push(e);
                    }
                } while (e);

                done = testCurrentChar();
                
                if (value.length > 0) {
                    value = new(tree.Expression)(value);
                    if (done) {
                        return value;
                    }
                    else {
                        result.push(value);
                    }
                    
                    if (parserInput.prevChar() === ' ') {
                        result.push(new tree.Anonymous(' ', index));
                    }
                }
                parserInput.save();
                
                value = parserInput.$parseUntil(tok);

                if (value) {
                    if (typeof value === 'string') {
                        error('Expected \'' + value + '\'', 'Parse');
                    }
                    if (value.length === 1 && value[0] === ' ') {
                        parserInput.forget();
                        return new tree.Anonymous('', index);
                    }
                    var item;
                    for (i = 0; i < value.length; i++) {
                        item = value[i];
                        if (Array.isArray(item)) {
                            
                            result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));
                        }
                        else {
                            if (i === value.length - 1) {
                                item = item.trim();
                            }
                            
                            var quote = new tree.Quoted('\'', item, true, index, fileInfo);
                            quote.variableRegex = /@([\w-]+)/g;
                            quote.propRegex = /\$([\w-]+)/g;
                            result.push(quote);
                        }
                    }
                    parserInput.forget();
                    return new tree.Expression(result, true);
                }
                parserInput.restore();
            }
function ( untilTokens ) { var i , e , done , value , tok = untilTokens || ';' , index = parserInput . i , result = [ ] ; function testCurrentChar ( ) { var char = parserInput . currentChar ( ) ; if ( typeof tok === 'string' ) { return char === tok ; } else { return tok . test ( char ) ; } } if ( testCurrentChar ( ) ) { return ; } value = [ ] ; do { e = this . comment ( ) ; if ( e ) { value . push ( e ) ; continue ; } e = this . entity ( ) ; if ( e ) { value . push ( e ) ; } } while ( e ) ; done = testCurrentChar ( ) ; if ( value . length > 0 ) { value = new ( tree . Expression ) ( value ) ; if ( done ) { return value ; } else { result . push ( value ) ; } // Preserve space before $parseUntil as it will not if ( parserInput . prevChar ( ) === ' ' ) { result . push ( new tree . Anonymous ( ' ' , index ) ) ; } } parserInput . save ( ) ; value = parserInput . $parseUntil ( tok ) ; if ( value ) { if ( typeof value === 'string' ) { error ( 'Expected \'' + value + '\'' , 'Parse' ) ; } if ( value . length === 1 && value [ 0 ] === ' ' ) { parserInput . forget ( ) ; return new tree . Anonymous ( '' , index ) ; } var item ; for ( i = 0 ; i < value . length ; i ++ ) { item = value [ i ] ; if ( Array . isArray ( item ) ) { // Treat actual quotes as normal quoted values result . push ( new tree . Quoted ( item [ 0 ] , item [ 1 ] , true , index , fileInfo ) ) ; } else { if ( i === value . length - 1 ) { item = item . trim ( ) ; } // Treat like quoted values, but replace vars like unquoted expressions var quote = new tree . Quoted ( '\'' , item , true , index , fileInfo ) ; quote . variableRegex = / @([\w-]+) / g ; quote . propRegex = / \$([\w-]+) / g ; result . push ( quote ) ; } } parserInput . forget ( ) ; return new tree . Expression ( result , true ) ; } parserInput . restore ( ) ; }
Used for custom properties, at-rules, and variables (as fallback)
Parses almost anything inside of {} [] () "" blocks
until it reaches outer-most tokens.

First, it will try to parse comments and entities to reach
the end. This is mostly like the Expression parser except no
math is allowed.
Used for custom properties at - rules and variables ( as fallback ) Parses almost anything inside of {} [] () blocks until it reaches outer - most tokens .