2008-12-10 2 views
9

Как вы определяете правила анализатора и лексера для анализа языка, который использует отступы для определения области.Как бы вы разобрали отступы (стиль python)?

Я уже нашел googled и нашел умный подход для его анализа, создав токены INDENT и DEDENT в лексере.

Пойду глубже по этой проблеме и отправлю ответ, если я приду к чему-то интересному, но я хотел бы увидеть другие подходы к проблеме.

EDIT: Как указал Чарли, there is already another thread very similar if not the same. Должно ли мое сообщение быть удалено?

ответ

1

Также вы можете отслеживать где-то в lexer, сколько идентификационных элементов предшествует первой строке и передать их парсеру. Самая интересная часть будет пытаться передать его парсеру правильно :) Если ваш синтаксический анализатор использует lookahead (здесь я имею в виду, что синтаксический анализатор может запрашивать переменное число токенов, прежде чем он действительно будет соответствовать даже одному), тогда попытка передать его через одну глобальную переменную кажется это очень плохая идея (потому что lexer может проскользнуть на следующей строке и изменить значение счетчика отступа, в то время как парсер все еще пытается разобрать предыдущую строку). Кроме того, во многих других случаях глобалы являются злыми;) Маркировка первой строки «реальный» токен каким-то образом с помощью счетчика отступов более разумна. Я не могу дать вам точный пример (я даже не знаю, какие генераторы парсера и лексера вы собираетесь использовать, если есть какие-либо ...), но что-то вроде хранения данных в токенах первой строки (это может быть неудобно, если вы можете " t легко получить такой токен от парсера) или сохранить пользовательские данные (карта, которая связывает токены с отступом, массив, где каждая строка в исходном коде как индекс и значение отступа в качестве значения элемента), кажется, достаточно. Одним из недостатков этого подхода является дополнительная сложность анализатора, которая должна будет различать значения идентификаторов и изменять их поведение на основе этого. Что-то вроде LOOKAHEAD ({yourConditionInJava}) для JavaCC может работать здесь, но это NOT очень хорошая идея. Множество дополнительных токенов в вашем подходе, кажется, менее злая вещь для использования :)

В качестве другой альтернативы я бы предложил использовать эти два подхода. Вы можете создавать дополнительные токены только тогда, когда счетчик отступа изменяет свое значение на следующей строке. Это похоже на искусственный маркер BEGIN и END. Таким образом, вы можете уменьшить количество «искусственных» токенов в потоке, поданных в парсер из lexer. Только ваша грамматика парсера должна быть скорректирована для понимания дополнительных токенов ...

Я не пробовал это (не имею никакого реального опыта в анализе таких языков), просто делясь мыслями о возможных решениях. Проверка уже построенных парсеров для таких языков может быть для вас очень полезной. Открытый исходный код - ваш друг;)

10

Это своего рода гипотетическое, поскольку это будет зависеть от того, какие технологии у вас есть для вашего лексера и синтаксического анализатора, но самый простой способ состоит в том, чтобы иметь маркеры BEGINBLOCK и ENDBLOCK, аналогичные фигурным скобкам в C. Используя "offsides rule", ваш лексер должен отслеживать стек уровней отмены. Когда уровень отступа увеличивается, испустите BEGINBLOCK для синтаксического анализатора; когда уровень отступов уменьшается, выпустите ENDBLOCK и выровняйте уровни со стека.

Here's another discussion этого на SO, кстати.

Смежные вопросы