Как показывает практика, токенизаторы не должны анализировать, а синтаксический анализатор не должен токенизировать.
В этом конкретном случае мне кажется маловероятным, чтобы каждое неукрашенное использование токена, подобного имени, - такогокак section
- обязательно будет tag
.Скорее всего, section
является тегом из-за его синтаксического контекста.Если токенизатор пытается пометить его как tag
, то он отслеживает синтаксический контекст, что означает, что он выполняет синтаксический анализ.
Сигилы .
и #
менее четкие.Вы можете считать их односимвольными токенами (за синтаксисом которых будет следовать имя) или вы можете считать их первым символом строки специального типа.Некоторые вещи, которые могут повлиять на вас так или иначе:
Можно ли отделить символ от следующего имени пробелом?(# mainWrapper
).Если это так, возможно, сигил является токеном.
Отличается ли лексическая форма класса или идентификатора от имени?Подумайте, например, об использовании специальных символов.Если вы не можете точно распознать объект, не зная, какой символ (если он есть) предшествовал ему, тогда его лучше рассматривать как один токен.
Существуют ли другие способы представления class
имен.Например, как вы представляете несколько классов?Некоторые возможности в моей голове:
#classA #classB
#(classA classB)
#"classA classB"
class = "classA classB"
Если какой-либо из вариантов, кроме первого, действителен, вам, вероятно, следует просто сделать #
токеном.Но правильная обработка строк в кавычках может создать другие проблемы.В частности, для этого может потребоваться повторная идентификация содержимого строкового литерала, что будет нарушением эвристики, которую парсеры не должны маркировать.К счастью, это не абсолютные правила;иногда необходима повторная компоновка.Но сведите его к минимуму.
Разделение на лексический и синтаксический анализ не должно быть смирительной рубашкой.Это метод организации кода, предназначенный для облегчения написания, понимания, отладки и документирования отдельных частей.Часто (но не всегда) случается, что разделение облегчает пользователям вашего языка понимание синтаксиса, что также важно.Но это не подходит для каждой задачи анализа, и точная граница является гибкой (но не пористой: вы можете поместить границу там, где она наиболее удобна, но как только она будет размещена, не пытайтесь протолкнуть вещи через трещины.)
Если вы обнаружите, что такое разделение задач слишком сложно для вашего проекта, вам следует либо пересмотреть свой языковой дизайн, либо попробовать анализ без сканирования.