LINUX.ORG.RU

Bison 3.2

 , , , ,


1

2

Bison — это генератор синтаксических анализаторов общего назначения, преобразующий аннотированную контексто-свободную граматику в детерминированный LR- или обобщённый LR(GLR)-анализатор, задействующий таблицы анализатора LALR(1). Bison также умеет генерировать таблицы IELR(1) и канонические LR(1). Овладев Bison, можно использовать его для разработки разнообразных языковых анализаторов — от применяющихся в простых настольных калькуляторах до сложных языков программирования. Bison обратно совместим с Yacc: все корректно составленные Yacc-грамматики должны работать с Bison без изменений.

В детерминистический C++-каркас, lalr1.cc, привнесены масштабные изменения. Если включена поддержка вариантов и компилятор поддерживает C++11 и выше — типы только для перемещения теперь можно использовать для семантических значений. Поддержка C++98 не объявлена устаревшей. Огромное спасибо Френку Хекенбаху за проторенный его реализацией каркаса на C++17 путь к этому выпуску.

Значимые изменения в этом выпуске:

  • Поддержка DJGPP, годами лишённого поддержки и тестирования, объявлена устаревшей. Если никто не гальванизирует этот труп — от него избавятся.
  • Также:
    • %printers должна использовать yyo вместо yyoutput для обозначения выходного потока.
    • Основанные на вариантах символы в C++ должны использовать emplace() вместо build().
    • В анализаторах на C++ parser::operator() теперь является синонимом для parser::parse.
  • Документация:
    • Добавлен новый раздел «Простой пример на С++» — руководство по написанию анализаторов на С++.
    • В генерируемый код теперь добавляется комментарий, что пользователям не следует завязываться на недокументированные детали реализации, например, начинающиеся на YY_ макросы.
  • Новые возможности:
    • C++: поддержка семантики перемещения (lalr1.cc)
    • C++: неявное перемещение правых значений (lalr1.cc)
    • C++: неявное семантическое действие по умолчанию теперь всегда вызов.
    • C++: переименование location.hh.
    • C++: stack.hh и position.hh объявлены устаревшими.
  • Исправлены:
    • Проблемы с переносимостью на MinGW и VS2015.
    • Проблемы с переносимостью в тестовом наборе.
    • Проблемы с переносимостью и предупреждения с Flex.

>>> Домашняя страница

>>> Сжатые исходники: .tar.gz (подпись), .tar.xz (подпись)

>>> Зеркало

>>> Подробности

а есть ли какой-нидь подробный хауту как всем этим пользоваться от идеи (с ликбезом про языки, грамматики и т.д.) до реализации в коде приложения в котором будет использоваться такой язык.

Меня все время не дает покоя мысль о том, что для решения прикладной задачи идеально использовать специализированный язык на котором ты уж пишешь свое решение. А не в корчах рожаешь его на быдло языке обмазываясь непонятными библами и прочим стаковерфлоу.

yax123 ★★★ ()
Ответ на: комментарий от yax123

для решения прикладной задачи идеально использовать специализированный язык на котором ты уж пишешь свое решение

при этом для 90% задач embedded DSL гораздо практичнее внешнего

annulen ★★★★★ ()
Ответ на: комментарий от yax123

Меня все время не дает покоя мысль о том, что для решения прикладной задачи идеально использовать специализированный язык на котором ты уж пишешь свое решение

На моем опыте это так, только есть штуки намного проще типа PEG, которые может и не могут распарсить правильно C++11 но это и не нужно, кастомный DSL должен быть простым и заточенным на домен, а не дженерики-лямбды-указатели.

loz ★★★★★ ()
Ответ на: комментарий от annulen

при этом для 90% задач embedded DSL гораздо практичнее внешнего

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

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

yax123 ★★★ ()
Ответ на: комментарий от loz

Сложно спорить.

ТАк где научиться придумывать свои языки, описывать их граматику, компелять парсер, встраивать его в проект и использовать по назначению?

yax123 ★★★ ()
Ответ на: комментарий от annulen

Дык я сам придумываю ТЗ. И думается мне, что в некоторых разработках DSL был бы очень кстати, только вот нет навыка его готовить и объяснить коллегам как это правильно нужно сделать, тоже не знаю.

yax123 ★★★ ()
Ответ на: комментарий от yax123

Внутренние DSL обыно получаются в результате рефакторинга, когда удается выделить дублирование из существующого кода, чтобы стало просто и красиво. Детали реализации будут зависеть от ЯП, в перле одни фишки используются, в рубях другие, в JS третьи

Внешний DSL должен быть крайне простым, до такой степени, что задача сама о нем просит. А если что-то сложное нужно, то это провод посмотреть в сторону форматов данных типа JSON, или встраивания полноценного ЯП типа Lua(JIT)

annulen ★★★★★ ()
Ответ на: комментарий от annulen

Ну вот вам такой пример. Делаем мы некий мегаприбор и к нему еще КПА (контрольно-проверочную аппаратуру). И внутре этой КПА должно быть реализовано тестирование мегаприбора. Причем тестирование может быть и весьма сложным и изощренным. И вот для написания этих тестов очень просится какой-нидь язык. Простое и очевидное решение прикрутить какой-нидь Lua. Но есть ощущение, что может лучше не Lua, а что-то самопальное располагающее к решению нашей задачи, хотя может и Lua хватит (мы еще не пробовали, но хотим). И вот хочется таки эту технологию охватить.

Фаулера я нашел (даже на русском), но не совсем ясно, есть ли там рецепт или просто абстрактные рассуждения на тему DSL.

yax123 ★★★ ()
Ответ на: комментарий от yax123

Простое и очевидное решение прикрутить какой-нидь Lua

Вот и надо сделать прототип на Lua и посмотреть, есть ли у такого рещения критичные недостатки по получившемуся синтаксису и другим параметрам. Кстати Lua отличнейший язык по части создания eDSL

В смысле уже внутри Lua-скриптов

annulen ★★★★★ ()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от annulen

Кстати Lua отличнейший язык по части создания eDSL
В смысле уже внутри Lua-скриптов

Че-че-че?

Я вкорячиваю луа, на луа пишу интерпретатор луадсл, и уже на нем пишу свое решение? Я правильно понял?

yax123 ★★★ ()
Ответ на: комментарий от yax123

Для DSL не нужны никакие dragon book) Где научится - этому особо не учат, Фаулера я немного читал - у него как-то все академично мне показалось.

Тут главное начать и понять что вобще возможно - берешь PEG реализацию для любимого языка, пишешь простой калькулятор. Для начала целые чиселки и пара операций без приоритетов. Делаешь простой REPL - читаешь строку, скармливаешь парсеру, печатаешь AST получившийся. Понимая как выглядит AST добавляешь штуку которая будет его вычислять и выдаешь результат вычислений уже.

Когда уложится в голове - усложняешь, можешь добавить флоатов, скобок, приоритет, функции типа pow, sqrt, что-угодно.

После этого берешь какой-то проект в котором ты разбираешься, на работе или домашний - и пытаешься к нему прикрутить DSL-интерфейс. Не везде это имеет смысл, понятно.

То есть, например, если это веб-сайт - описываешь события каким-то форматом, парсишь их и выполняешь нужные действия в системе.

Например может получится такой «testing framework»:

Anonymous user opens page '/'.
Anonymous user logins with {username: 'vasya', password: 'yo'}.
Server throws error 'user_does_not_exist'.

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

loz ★★★★★ ()
Ответ на: комментарий от yax123

Документацию читать или гуглить не пробовал? Несколько лет назад в универе писали свой крошечный язык на Lex+Yacc (Flex+Bison в случае GNU). Проблем особо не возникало. В гугле примеры были.

anonymous ()
Ответ на: комментарий от yax123

И вот для написания этих тестов очень просится какой-нидь язык.

Вообще сильно зависит от сложности прибора и сложности тестов, но в простейшем случае я начал бы с data-driven алгоритмов. Т.е. например если тесты - просто последовательность каких-то записей в регистры для изменения состояния устройства и чтения из регистров для проверки состояния, то DSL вырождается в две команды (ну ещё пауза в миллисекундах если прибор не мгновенно реагирует), которые проще в текстовые файлы вгонять и парсить эти текстовые файлы тривиально ручками:

# w port value  -- writes value to port
# p milliseconds  -- pauses test execution
# r port expectedValue  -- reads value from port and compares

w 100 0xf000
p 10
w 100 0xffff
p 10
r 100 0xffff

Если же нужны условия и прочие там циклы (например разное продолжение алгоритма тестирования в зависимости от возвращённого прибором значения), то я бы забабахал внутренний DSL:


using namespace testMethods;
// ну или от класса отнаследоваться, объявляющего w(), r(), p().

void testDevice() {
   w(100, 0xf000);
   p(10);
   w(100, 0xffff);
   p(10);
   r(100, 0xffff);  // падает если возвращено не 0xffff
   // overloaded-версия r() с одним аргументом просто возвращает прочитанное значение
   if (r(100) != 0xffff) {
       // ...
   }
}

Хм. А неплохо вышло. Собственно, я бы его в обоих случаях забабахал бы. Делать мне больше нечего как парсеры писать, даже примитивные. А тут и проверка кода компилятором, и помощь от IDE, и бесконечные возможности расширения функционала. И никакие lua не нужны, всё на основном языке проекта (каким бы он ни был).

В обоих случаях бизон - это межконтинентальной баллистической ракетой по воробьям.

dimgel ()
Последнее исправление: dimgel (всего исправлений: 2)
Ответ на: комментарий от yax123

на луа пишу интерпретатор луадсл

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

foo { x = 1, y =2 }
bar "baz"
annulen ★★★★★ ()
Ответ на: комментарий от annulen

а тут уже не стоит с шашкой наголо кидаться

+0.5: есть же ещё рекурсия по коду. (Каждому мужику символу грамматики - по бабе методу!) Для LL(1) она предпочтительнее потому что неизмеримо нагляднее и проще для отладки по сравнению с таблично-управляемыми, даже если тоже сгенерирована из БНФ.

dimgel ()
Последнее исправление: dimgel (всего исправлений: 2)
Ответ на: комментарий от yax123

У них (flex, bison) есть info (info flex; info bison). Они весьма подробные, там есть примеры, можно накопипастить калькулятор числовых выражений. Умные словы LL, LALR долго не будут нужны.

anonymous ()
Ответ на: комментарий от Tuxman

Потому что очередное г-но от товарищей мозолеедов из GNU, очевидно. После ANTLR, где есть и графический testbed для дебаггинга синтаксиса, и интеграция с эклипсом, и с кучей ЯП/систем сборки, на связку flex+bison начинаешь смотреть с лёгкой ухмылкой, примерно как на набор детских игрушек.

Я вот что заметил, что в 2018 году любое поделие от GNU абсолютно всегда можно заменить на что-то аналогичное не от них, выиграв в удобстве, надёжности и скорости разработки. GCC нужно заменять на clang, gdb на lldb, автолулзы (буээ) - на cmake, ну и так далее.

anonymous ()
Ответ на: комментарий от anonymous

После ANTLR, где есть и графический testbed для дебаггинга синтаксиса, и интеграция с эклипсом, и с кучей ЯП/систем сборки, на связку flex+bison начинаешь смотреть с лёгкой ухмылкой, примерно как на набор детских игрушек.

Во, точно, оно antlr называлось. Генерило рекурсию по коду. А оно LALR уже умеет? И если да, то каким чудом? Интеграция с eclipse и графический отладчик — это шашечки. А вот грамматику C++ описать на нём ты не сможешь. А bison, помнится, использовался в gcc (хз как щас). Так что что здесь детская игрушка, а что — инструмент для серьёзных пацанов, это ещё большой вопрос.

dimgel ()
Ответ на: комментарий от yax123

а есть ли какой-нидь подробный хауту как всем этим пользоваться

Есть. B.Kernigan, R.Pike, «The Unix Programming Environment», Prentice Hall, 1984. ISBN 0-13-937681-X

На русский язык переводилась минимум дважды под разными названиями.

vitus ()
Ответ на: комментарий от yax123

YML + LUA

Для простого описания в 90% случаев хватит YML.

Если хочется добавить логику - lua вполне подойдет.

Если все-таки все еще хочется писать DSL, надо учесть что этому DSL-у ты будешь потом всех обучать. Значит надо будет писать документацию getting started, примеры и всякое такое. Но если не пугает - то есть простой способ начать с https://archive.codeplex.com/?p=irony

anonymous ()

Мой единственный опыт общения с Flex+Bison много лет назад состоял в том, что я скормил генератору формальное описание языка VRML и получил на выходе сгенерированный код парсера, впадающий в бесконечный цикл.

Я не виню в этом инструментарий. Скорее всего, я действительно что-то не дочитал в документации. Но что именно я упустил, понять было затруднительно, а пытаться отлаживать простыню автосгенерированного кода — то ещё упражнение для джедая. Поскольку задача делалась чисто for fun, на этом всё и закончилось. Возможно, как-нибудь потыкаю Flex+Bison ещё разок...

Поддержка C++98 не объявлена устаревшей.

Это радует.

hobbit ★★★★★ ()
Последнее исправление: hobbit (всего исправлений: 1)