Надо ли использовать YACC, LEX и подобные инструменты
Первый вопрос, который задаёт себе разработчик компилятора, это «как»?
Генераторы YACC и LEX помогают решить эту проблему.
Возникает резонный вопрос: «Нужно ли их использовать?
Задача разработки и сопровождения компилятора решается с ними легче или нет?
Страхует ли они от ошибок или их провоцируют?»
Вот мнение Дейкстры по этому поводу:
В шестидесятые годы она [наука] разработала теорию синтаксического разбора, необходимую для поднятия уровня компиляторов выше уровня поделок,
напичканных ошибками, и превратив её в предмет, пригодный для обучения.
Это было главное достижение: я, например, помню весьма отчетливо, как в 1962 те из нас,
кто действительно написал компилятор, выглядели в глазах остальных как некие полубоги.
В связи с этим достижением я бы хотел подчеркнуть, что этого никогда бы не произошло,
если бы мы со временем не научились давать формальное определение синтаксиса компилируемого языка:
без этого формального определения слишком сложно было бы определить существование проблемы компиляции.
Он прямо не призывает использовать YACC, LEX и им подобные инструменты.
Но он призывает опираться на науку.
На неё же опираются генераторы синтаксических анализаторов.
Но вот другое мнение, мнение практика, который не только разрабатывал компиляторы (Zortech C++, D),
он ещё и автор языка D. Это Уолтер Брайт. Из интервью с ним:
Вопрос:
Еще раз касательно вашего вышесказанного комментария про ошибки программирования,
анализаторы YACC LALR нелюбимы за получаемые сообщения типа «где-то тут есть ошибка, но я не уверен, где именно».
Ruby особенно плох в этом плане — вы хотите сказать, что D использует лучший «мешок фокусов» чем YACC?
Уолтер Брайт
Я никогда не использовал YACC; все сделанные мной лексеры и анализаторы полностью самодельные.
Хорошее диагностирование ошибок, хорошее восстановление после ошибок для того,
чтобы анализ мог быть продолжен без генерации моря ложных сообщений, — всё это в большей степени искусство, чем наука.
Андрей Хохлов, разрабатывая свой язык Context, для одних версий компилятора применял Flex и Bison,
для других нет. На вопрос «как легче, с Flex и Bison или без них», он ответил, что особой разницы в трудозатратах он не заметил.
Отвечая на вопрос «с ними или без», нужно в случае утвердительного ответа ответить на вопрос «какой именно».
Многие генераторы синтаксических анализаторов привязаны к инструментальному языку.
Lex/Flex и YACC/Bison написаны на Си и генерируют код на нём же.
CocoR «привязан» к C#, antlr, ... — к Java.
Есть ещё один чисто практический вопрос: какой алфавит и какую кодировку будет использовать будущий язык программирования?
Если алфавит включает в себя что-то кроме стандартной латиницы, и программы на будущем языке будут писать в utf-8,
сразу возникают проблемы в использовании Lex/Flex.
Они не поддерживают напрямую Юникод.
Текстовые константы придётся записывать примерно в таком виде:
"\u0435\u0441\u043B\u0438\u0020\u0410\u0020"
Что весьма ненаглядно и неудобно.
Есть ещё одна причина отказаться, как минимум, от генератора лексеров типа Lex/Flex.
Они создают лексеры с фиксированным алфавитом и набором ключевых слов.
Если компилятор должен по очереди работать, к примеру, с русским алфавитом и набором ключевых слов,
а потом переключаться на английский вариант, то созданные с помощью Lex/Flex не смогут обеспечить такого переключения «на лету».
Они слишком статичны для этого, они не могут менять своё поведение в динамике.
Поэтому в многоязыковом программировании они нам не помощники.
В теории можно создать свой лексер, который бы подавал на вход генератора парсеров
YACC/Bison то же самое, что и отвергнутые Lex/Flex.
Однако задача эта не из тривиальных.
Опубликовано: 2015.01.02, последняя правка: 2019.01.28 20:50
Отзывы
✅ 2015/05/19 11:56, rst256 #0
На практике в любом случае очень многое придется дописывать вручную. У всех этих анализаторов для описания грамматики используется нотация семейства BNF (extBNF, ABNF, etc...), которая обладает очень ограниченными возможностями. К примеру, приоритет для математических операций, комментарии экранирование символов и т.п. она не осилит. Контекстные условия тоже. А вот тонкости "Многоязычного программирования" наоборот для этих анализаторов вполне по плечу (это же банальные регулярные преобразования). Разве что поддержка (точнее, её отсутствие) юникода на Си может доставить немного проблем.
P.S. Кстати, если кому будет интересна тема синтаксических анализаторов для языков прогрограммирования, рекомендую: Братчиков И.Л. "Синтаксис языков программирования". http://publ.lib.ru/ARCHIVES/B/BRATCHIKOV_Igor'_Leonidovich/_Bratchikov_I.L..html И вот что интересно: книга написана аж в 1975 году, но до сих пор актуальна, т.к. в данной области с тех пор почти ничего не изменилось...✅ 2016/04/03 16:25, Вежливый Лис #1
Надо заплатить константой за разрешение ограничений YACC и спокойно использовать Earley+SPPF. Добавить свой отзыв
Написать автору можно на электронную почту mail(аt)compiler.su
|