2013-07-05 1 views
0

Я нашел несколько дней назад очень хороший подход к синтаксическому анализу css -строки (даже вложенные) в json. Однако, похоже, что в этом есть большая проблема.css to json parser Замораживает окно браузера

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

Если мы попытаемся разобрать css -string, он будет убить окно браузера, не знает, что здесь происходит ... Я уже an issue но открытая компанию нет никого, чтобы ответить на потому что хранитель Дэвид Эллис потерян.

Любые идеи/предложения?

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/

+0

Вы пробовали отлаживать код и проверять, на какой строке застрял браузер? – jbkkd

+0

@jbkkd Конечно, я пробовал ... Однако нелегко отладить что-то вроде этого, что убивает каждый экземпляр браузера менее чем за одну секунду;) – yckart

+0

См. Мой ответ ниже. – jbkkd

ответ

0

Выполнение кода, похоже, что он просто не работает.

Он достигает бесконечный цикл, так как это регулярное выражение не удается после первого запуска:

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

Следовательно, почему браузер застрял. Он также не возвращает правильный JSON.

Я бы посоветовал написать что-то подобное самостоятельно или попытаться отладить и исправить существующий код.