Подтвердить что ты не робот

Antlr4 Слушатели и посетители - что реализовать?

Я читаю "The Definitive Antlr 4 Reference" и понимаю, как работают слушатели и посетители. В книге особенно хорошо объясняется, как слушатели относятся к синтаксическим анализаторам SAX и делают это очевидным, когда методы будут вызываться во время реализации каждого из них. Я также вижу, что слушатели вполне подходят для преобразования ввода в вывод, но я хотел бы получить краткое объяснение/пример того, когда использовать прослушиватель и когда использовать посетителя (или оба они будут использоваться в некоторых случаях?).

Мое особое намерение заключается в создании интерпретатора (Cucumber-style/TinyBasic Interpreter с некоторыми пользовательскими вызовами), который будет проверять наличие синтаксических ошибок и прекратить выполнение ошибки из пользовательской функции без восстановления - хотелось бы видеть полную реализацию такая вещь в antlr - если кто-то знает об этом.

Заранее благодарим за любые советы.

4b9b3361

Ответ 1

Если вы планируете напрямую использовать вывод синтаксического анализатора для интерпретации, посетитель является хорошим выбором. Вы полностью контролируете обход, поэтому в условных ситуациях посещается только одна ветвь, петли можно посещать n раз и т.д.

Если вы переводите ввод на более низкий уровень, например. инструкции виртуальной машины, оба шаблона могут быть полезны.

Вы можете взглянуть на "Шаблоны реализации языка", который охватывает основные реализации интерпретатора.

В основном я использую шаблон посетителя, поскольку он более гибкий.

Ответ 2

Вот цитата из книги, которая, на мой взгляд, актуальна:

Самое большое различие между механизмами слушателя и посетителя заключается в том, что методы прослушивателя вызываются объектом walker, предоставленным ANTLR, в то время как методы посетителей должны перемещать своих детей с явным вызовом посещения. Забытие вызова функции посещения() в node s означает, что эти поддеревья не посещаются.

В шаблоне посетителей у вас есть возможность направлять движение по дереву в то время как в слушателе вы реагируете только на ходок по дереву.

Ответ 3

Существует еще одно важное различие между этими двумя шаблонами: посетитель использует стек вызовов для управления обходами дерева, тогда как слушатель использует явный стек, выделенный в куче, управляемый ходуном. Это означает, что большие входные данные для посетителя могут выбить стек, в то время как слушатель не будет иметь проблем.

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