Итак, в основном я хочу проанализировать структуру CSS-кода в PHP, используя лексер/парсер, сгенерированный пакетами PEAR PHP_LexerGenerator и PHP_ParserGenerator. Моя цель - разобрать файлы следующим образом:
selector, selector2 {
prop: value;
prop2 /*comment */ :
value;
subselector {
prop: value;
subsub { prop: value; }
}
}
Это все нормально, пока у меня нет псевдоклассов. Псевдоклассы позволяют добавлять :
и имя CSS ([a-z][a-z0-9]*
) к элементу, как в a.menu:visited
. Будучи несколько ленивым, синтаксический анализатор не имеет списка допустимых псевдоклассов и принимает все за имя класса.
Моя грамматика (без учета всех особых случаев и пробелов) выглядит так:
document ::= (<rule>)*
rule ::= <selector> '{' (<content>)* '}'
content ::= <rule>
content ::= <definition>
definition ::= <name> ':' <name> ';'
// h1 .class.class2#id :visited
<selector> ::= <name> (('.'|'#') <name>)* (':' <name>)?
Теперь, когда я пытаюсь проанализировать следующее
h1 {
test:visited {
simple: case;
}
}
Анализатор жалуется, что ожидал, что за двойным двоеточием следует <name>
. Поэтому он пытается прочитать simple:
как <selector>
(просто посмотрите на подсветку синтаксиса SO).
Это моя ошибка, что синтаксический анализатор не может отследить достаточно, чтобы попробовать правило <definition>
? Или Лимон просто недостаточно силен, чтобы выразить это? Если да, то что я могу сделать, чтобы синтаксический анализатор работал с этой грамматикой?
select1, select2 { ... }
. Нет правила, которое обрабатывает «список селекторов, разделенных запятыми». - person Jonathan Leffler   schedule 10.10.2011