Boost Spirit: «Семантические действия – это зло»?

Чтение и просмотр этой презентации: http://boost-spirit.com/home/2011/06/12/ast-construction-with-the-universal-tree/
Я обнаружил это утверждение – в основном нам предлагается не использовать семантические действия.

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

Поэтому я хотел бы спросить: это «официальный» пункт? Должен ли я научиться работать с грамматикой атрибутов и более подробно избегать семантических действий? Если это так – я бы хотел спросить некоторые базовые (возможно, даже тривиальные) примеры, демонстрирующие такой подход – интерпретатор LISP слишком сложен для меня, чтобы пережевывать …

Я уверен, что Гартмут ответит через секунду. До тех пор это мое взятие:

Нет , это не официальный вопрос.

У семантических действий есть некоторые недостатки

  • Простейшим недостатком семантических действий является стилистическое понятие разделения проблем . Вы хотите выразить синтаксис в одном месте и семантику в другом. Это помогает ремонтопригодности (особенно в отношении длительных сроков компиляции для составления грамматик духа)

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

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

  • Семантические действия имеют тенденцию (но не обязательно так), чтобы ввести больше копий по значению; это, в сочетании с тяжелым возвратом назад, может снизить производительность . Конечно, если семантическое действие «тяжелое», это само по себе будет препятствовать выполнению parsingа.


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

  1. Рассмотрим использование qi::locals<> и унаследованных атрибутов (код из Mini XML - ASTs! ) – они include семантические действия:

     xml = start_tag [at_c<0>(_val) = _1] >> *node >> end_tag(at_c<0>(_val)) // passing the name from the // ... start_tag as inherited attribute ; 

    Или используя qi :: locals :

     rule > rl; rl = alpha[_a = _1] >> char_(_a); // get two identical characters test_parser("aa", rl); // pass test_parser("ax", rl); // fail 

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

  2. Кроме того, некоторые рабочие места действительно «быстро и грязно» и не требуют использования utree или ручного типа AST:

      qi::phrase_parse(first, last, // imagine qi::istream_iterator... intesting_string_pattern // we want to match certain patterns on the fly [ log_interesting_strings ], // and pass them to our logger noise_skipper // but we skip all noise ); 

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

  3. Семантические действия являются зеркальным отображением семантических действий в Духе Карма, где они обычно представляют меньше проблем, чем в Ци; поэтому даже если только для согласованности интерфейса / API, семантические действия являются «хорошей вещью» и повышают удобство использования Boost Spirit в целом.

  • //! в исходном коде Qt
  • Лучше ли создать одноэлементный доступ к контейнеру единства или передать его через приложение?
  • Заменить часть строки другой строкой
  • Что такое делегат C ++?
  • Монокомпилятор как услуга (MCS)
  • Как выполнить итерацию свойств анонимного объекта в C #?
  • Недопустимый пробел и его нельзя удалить?
  • Разница между std :: result_of и decltype
  • Что означает знак вопроса и двоеточие (?: Trernary operator) в объективе-c?
  • Как использовать строку C ++ в структуре, когда malloc () - с той же структурой?
  • Именование включает охранников
  • Interesting Posts

    Скрипт для связывания расширения с программой

    Как создать RESTful поиск / фильтрацию?

    Net :: SMTPAuthenticationError при отправке электронной почты из приложения Rails (в промежуточной среде)

    Как включить динамический массив INSIDE a struct в C?

    Как выборочно маршрутизировать сетевой трафик через VPN на Mac OS X Leopard?

    Как передать некоторые данные от одного controllerа другому controllerу-сверстнику

    Почему IETF специально выбрал 192.168 / 16 для частного класса IP-адресов?

    Как нажимать массив объектов в массив в мангусте с одним вызовом?

    Как добавить обычного пользователя в файл sudoers?

    Кто-нибудь знает набор привязок C # для FFMPEG?

    Последствия поддержки нескольких пользователей Android (новые в версии 4.2) для модели данных на стороне сервера (например, android_id)

    Многомерный массив vs

    Как найти утечку памяти в коде / проекте на C ++?

    Разница ключевых слов «typename» и «class» в шаблонах?

    В чем разница между «.equals» и «==»?

    Давайте будем гением компьютера.