Domanda

I found some days ago a really nice approach to parse css-strings (even nested) to json. However, it seems, that there's somewhere a big problem in it.

https://github.com/csvplot/cml-parse

If we try to parse a css-string, it will kill the browser window, don't know what's going on here... I already opend an issue but there's no one to answer the issue, since the maintainer David Ellis is lost.

Any ideas/suggestions?

function parse(data) {
    var stateStack = [];
    var scopeStack = [];
    var outObj = {};

    while(data) {

        // Grab current number of indentation characters
        /^(\s*)/.test(data);
        // If we've entered any state, and that state is not an explicit block declaration ( {}'s ) and we have an indent level smaller than the most recent indent level,
        // then remove the most recent scope level and recall the state back to the previous scope's state
        if(stateStack.length &&
           stateStack[stateStack.length-1] !== 'explicitBlock' &&
           scopeStack.length &&
           RegExp.$1.length < scopeStack[scopeStack.length-1].indent) {
            scopeStack.pop();
            while(stateStack.length && (stateStack[stateStack.length-1] !== 'block' || stateStack[stateStack.length-1] !== 'explicitBlock')) {
                stateStack.pop();
            }
        }
        // If current chunk is the key to an object
        if(/^(\s*)([^:]*)\s*([{\n])/.test(data)) {
            // Grab the indent size of the key and the current outObj position from the scope stack
            var indentLength = RegExp.$1.length;
            var currScope = (scopeStack.length ? scopeStack[scopeStack.length-1].ref : outObj);
            // Split the identifier by spaces and construct/traverse down the defined path
            // TODO: Figure out how to handle commas that define the same inner content along multiple paths
            RegExp.$2.split(/\s*/).forEach(function(scope) {
                if(scope !== '') {
                    currScope[scope] = currScope[scope] || {};
                    currScope = currScope[scope];
                }
            });
            // Push the deepest scope and the current indent length onto the scope stack, and push the explicitBlock vs block state onto the state stack
            // TODO: Work on a state diagram to truly handle all of the possible states involved properly
            scopeStack.push({ref: currScope, indent: indentLength});
            stateStack.push(RegExp.$3 === '{' ? 'explicitBlock' : 'block');
            // Rip out the handled chunk of data from the string
            data = data.replace(/^\s*[^:]*\s*[{\n]/, '');
        }
    }
    return data;
}

http://fiddle.jshell.net/5pTBr/

È stato utile?

Soluzione

Running the code, it looks like it just does not work.

It reaches an infinite loop since this regex is failing after the first run:

if(/^(\s*)([^:]*)\s*([{\n])/.test(data)) {

Hence why the browser is stuck. It also does not return the correct JSON.

I'd advise on writing something like this by yourself, or trying to debug and fix the existing code.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top