Показать сообщение отдельно
  #1 (permalink)  
Старый 29.01.2012, 15:31
Особый гость
Посмотреть профиль Найти все сообщения от monolithed
 
Регистрация: 02.04.2010
Сообщений: 4,260

Разбор вложенных структур (парсинг CSS)
Задача не совсем типичная, хочу написать небольшой анализатор кода для разбора вложенных структур, которые должны транслироваться в валидный CSS.
Однако не получается захватить идентификаторы родительских селекторов.

Пример вложенной структуры:
#foo {
        border: 1px;
        a {
                border: 2px;
        }
        b {
                border: 3px;
                c {
                        border: 4px; /* comment */
                }
        }
}

То, что я хочу получить в итоге:
#foo {
        border: 1px;
}
 
#foo a {
        border: 2px;
}
 
#foo b {
        border: 3px;
}
 
#foo b c {
        border: 4px; /* comment */
}

Пока что получилось добиться такого результата:
c {
	border: 4px; /* comment */
}

b {
	border: 3px;
}

a {
	border: 2px;
}

#foo {
	border: 1px;
}


Код, который выполняет разбор (на С++ правда, лень было переписывать на JS, но надеюсь будет понятно, т.к. там нужно только итератор на charAt() заменить )
#include <iostream>
#include <iterator>
#include <string>

using namespace std;

int main() {

    string str = "\
    #foo {\
        border: 1px;\
        a {\
            border: 2px;\
        }\
        b {\
            border: 3px;\
            c {\
                border: 4px; /* comment */\
            }\
        }\
    }";

    string::const_iterator i = str.end(), begin = str.begin(), end;

    while (i != begin) {
        if (*i == ';' || (*i == '/' && *(i-1) == '*')) {
            end = i++;

            while (*i-- != '{');

            while (true) {
                if (*i == ';' || *i == '}' || *i == '{' || i == begin)
                    break;
                i--;
            }

            string item(++i, ++end);
            cout << item << "}" << endl;
        }
        i--;
    }

    return 0;
}


Возможно я не так начал разбор, но идея была такая: сперва получить идентификаторы, которых мне не хватает, а затем объеденить с тем что есть. Осталось собрать имена селекторов.

Иными словами мне нужно получить массив с такими селекторами:
['#foo', '#foo a', '#foo b', '#foo b c']


Если есть какие-то идеи по поводу алгоритма с удовольствием выслушаю.

Последний раз редактировалось monolithed, 29.01.2012 в 15:43.
Ответить с цитированием