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 в целом.

  • выделение разделяемой памяти
  • Фиксированная очередь размера, которая автоматически отбрасывает старые значения при появлении новых enques
  • LINQ Где игнорировать акцентуацию и случай
  • Анонимный союз C ++ 11 с нетривиальными членами
  • Как разобрать csv с помощью boost :: spirit
  • Получить имя свойства как строку
  • Память использования проблем в C
  • Где shared_ptr?
  • Entity Framework / SQL2008 - Как автоматически обновлять поля LastModified для объектов?
  • Как использовать ключевое слово Java в стиле Java в C #?
  • Что означает оператор?? =?
  • Давайте будем гением компьютера.