Я пытаюсь проанализировать CSS или, по крайней мере, основы, используя ANTLR. Я сталкиваюсь с несколькими проблемами с моими правилами лексера все же. Проблема заключается в неоднозначности между селекторами идентификаторов и шестнадцатеричными значениями цвета. Используя упрощенную грамматику для ясности, рассмотрим следующий ввод:
#bbb {
color: #fff;
}
и следующие правила парсера:
ruleset : selector '{' property* '}';
selector: '#' ALPHANUM;
property: ALPHANUM ':' value ';' ;
value: COLOR;
и эти токены лексера:
ALPHANUM : ('a'..'z' | '0'..'9')+;
COLOR : '#' ('0'..'9' | 'a'..'f')+;
Это не будет работать, потому что #bbb маркируется как токен COLOR, даже если он должен быть селектором. Если я изменю селектор, чтобы он не начинался с шестнадцатеричного символа, он работает нормально. Я не уверен, как решить это. Есть ли способ сказать ANTLR, что он должен обрабатывать определенный токен только как токен COLOR, если он находится в определенной позиции? Скажем, если это правило правила, я могу смело предположить, что это цветной маркер. Если это не так, относитесь к нему как к селектору.
Любая помощь будет оценена!
Решение: Оказывается, я пытался сделать слишком много в грамматике, с которой мне, вероятно, следует иметь дело в коде, использующем AST. В CSS слишком много неоднозначных токенов, чтобы надежно разбить их на разные токены, поэтому подход, который я сейчас использую, состоит в основном в токенизации специальных символов, таких как '#', '.', ':' И фигурных скобок, и выполнении постобработки в потребительский код. Работает намного лучше, и легче справляться с крайними случаями.