Как бы вы определили свои правила синтаксического анализатора и лексера для анализа языка, который использует отступы для определения области видимости.
Я уже погуглил и нашел умный подход к его синтаксическому анализу, создав токены INDENT и DEDENT в лексере.
Я углублюсь в эту проблему и опубликую ответ, если найду что-нибудь интересное, но я хотел бы увидеть другие подходы к проблеме.
Обновлено: Как указал Чарли, уже есть другой поток, очень похожий, если не такой. Должен ли мой пост быть удален?






Также вы можете отследить где-нибудь в лексере, сколько элементов идентификатора предшествует первой строке, и передать это парсеру. Самая интересная часть - попытаться правильно передать его синтаксическому анализатору :) Если ваш синтаксический анализатор использует опережающий просмотр (здесь я имею в виду, что синтаксический анализатор может запрашивать переменное количество токенов, прежде чем он действительно будет соответствовать хотя бы одному), то попытка передать его через одну глобальную переменную кажется это очень плохая идея (потому что лексер может проскользнуть на следующей строке и изменить значение счетчика отступов, пока синтаксический анализатор все еще пытается проанализировать предыдущую строку). Также глобальные переменные - зло во многих других случаях;) Пометка первой строки «реального» токена каким-либо образом с помощью счетчика отступов более разумна. Я не могу привести вам точный пример (я даже не знаю, какие генераторы парсеров и лексеров вы собираетесь использовать, если они есть ...), но что-то вроде хранения данных в токенах первой строки (это может быть неудобно, если вы можете '' t легко получить такой токен из парсера) или сохранить пользовательские данные (карта, которая связывает токены с отступом, массив, где каждая строка в исходном коде как индекс и значение отступа как значение элемента) кажется достаточно. Одним из недостатков этого подхода является дополнительная сложность синтаксического анализатора, который должен будет различать значения идентификатора и изменять свое поведение на основе этого. Что-то вроде LOOKAHEAD ({yourConditionInJava}) для JavaCC может работать здесь, но это НЕТ - очень хорошая идея. Множество дополнительных токенов в вашем подходе, кажется, будет менее опасным для использования :)
В качестве другой альтернативы я бы предложил смешать эти два подхода. Вы можете сгенерировать дополнительные токены только тогда, когда счетчик отступов изменит свое значение в следующей строке. Это похоже на искусственный токен BEGIN и END. Таким образом вы можете уменьшить количество «искусственных» токенов в потоке, передаваемых в парсер из лексера. Только грамматика вашего парсера должна быть скорректирована, чтобы понимать дополнительные токены ...
Я этого не пробовал (у меня нет реального опыта парсинга таких языков), просто поделился своими мыслями о возможных решениях. Проверка уже созданных парсеров для таких языков может быть для вас очень полезна. Открытый исходный код - ваш друг;)
Это в некотором роде гипотетически, поскольку это будет зависеть от того, какая технология у вас есть для вашего лексера и парсера, но, по-видимому, самый простой способ - иметь токены BEGINBLOCK и ENDBLOCK, аналогичные фигурным скобкам в C.Использование "офсайды" ваш лексер должен отслеживать стопки уровней отступов. Когда уровень отступа увеличивается, испускает BEGINBLOCK для синтаксического анализатора; когда уровень отступа уменьшается, генерирует ENDBLOCK и выталкивает уровни из стека.
Вот еще одно обсуждение этого на SO, кстати.