Видите ли вы странные ошибки линкера определения символов, упоминающие<boost::mpl::failed
>и<boost::spirit::qi::rule
>? Тогда эта запись FAQ может быть для вас.
Boost.Mplреализует макрос<BOOST_MPL_ASSERT_MSG()
>, который по существу является более мощной версией static_assert. К сожалению, при определенных обстоятельствах использование этого макроса может привести к вышеупомянутым ошибкам линкера.
Spiritпозволяет определить константу препроцессора, отключающую использование<BOOST_MPL_ASSERT_MSG()
>, при переходе на<BOOST_STATIC_ASSERT()
>. Для этого необходимо определить BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG=1. Сделайте это, добавив
-DBOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG=1
на командной строке компилятора или путем вставки
#define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG 1
Введите свой код до того, как будут включены заголовки Spirit.
Использование этого трюка не оказывает негативного влияния на функциональностьДуха. Единственное изменение, которое вы можете увидеть при использовании этого обходного пути, это менее многословные сообщения об ошибках, генерируемые из static_assert.
В каталоге «Усиление/Дух» в настоящее время хранятся две версии библиотеки «Дух»:Spirit.Classic(бывший V1.8.x) и SpiritV2. Оба являются полностью независимыми и обычно не используются одновременно. Не смешивайте их в одной и той же грамматике.
Дух.Классикаразвивалась годами в довольно сложной структуре каталогов:
boost/spirit/actor
boost/spirit/attribute
boost/spirit/core
boost/spirit/debug
boost/spirit/dynamic
boost/spirit/error_handling
boost/spirit/iterator
boost/spirit/meta
boost/spirit/symbols
boost/spirit/tree
boost/spirit/utility
Вводя Spirit V2, мы реструктурировали структуру каталога, чтобы вместить две версии одновременно. ВсеSpirit.Classicтеперь живет в каталоге
boost/spirit/home/classic
где приведенные выше каталоги содержат пересылающие заголовки в новое местоположение, позволяющее поддерживать совместимость приложений. Заголовки пересылки выдают предупреждение (начиная с Boost V1.38), в котором пользователю предлагается изменить маршруты включения. Пожалуйста, ожидайте, что вышеупомянутые каталоги/передающие заголовки скоро исчезнут.
Это объясняет необходимость каталога
boost/spirit/include
который также содержит пересылаемые заголовки. Но на этот раз заголовки не исчезнут. Мы рекомендуем авторам приложений использовать только включения, содержащиеся в этом каталоге. Это позволяет нам при необходимости реструктурировать каталоги, не беспокоясь о совместимости приложений. Пожалуйста, используйте эти файлы только в своем приложении. Если окажется, что какой-то файл пересылки отсутствует, пожалуйста, сообщите об этом как об ошибке.
Дух V2 больше не является только разбором (какДух.Классика). Он состоит из 3 частей (подбиблиотеки):Дух.Qi,Дух. КармаиДух.ЛексФайлы заголовков для тех, кто живет в
boost/spirit/home/qi
boost/spirit/home/karma
boost/spirit/home/lex
и иметь заголовки в
boost/spirit/include
Spirit.Qiявляется прямым преемникомSpirit.Classic, поскольку он реализует DSEL (специфичный для домена встроенный язык), позволяющий писать парсеры с использованием синтаксиса самого C++ (парсеры в смысле превращения последовательности байтов во внутреннюю структуру данных). Он не совместим с.Дух.Классика, однако, основные понятия схожи.
Дух.Кармаявляется аналогом.Spirit.Qi. Он реализует аналогичный DSEL, но для записи генераторов (т.е. вещей, превращающих внутренние структуры данных в последовательность байтов, большую часть времени - строк).Дух.Карма- это ЯнДух. ЦиИнь, это почти как зеркальная картина.
Spirit.Lex— это библиотека, позволяющая писать лексические анализаторы. Они либо пригодны для использования отдельно, либо могут использоваться в качестве передней части.Дух.Qiпарсеры. Если вы знаете flex, у вас не должно быть проблем с пониманиемSpirit.Lex. Эта библиотека фактически не реализует сам лексер. Все, что он делает, это предоставляет интерфейс для уже существующих лексических анализаторов. В настоящее время он использует превосходную библиотеку Бена ХансонаЛексертля(предлагается для обзора Boost, BTW) в качестве основной рабочей лошадки.
Опять же, не используйте файлы заголовка под каталогом boost/spirit/home напрямую, всегда включайте файлы из каталога boost/spirit/include.
Последний бит отсутствуетBoost.Phoenix(который в настоящее время все еще живет под зонтиком Spirit, но уже был принят в качестве библиотеки Boost, поэтому он отойдет).Boost.Phoenix— это библиотека, позволяющая писать функциональный стиль C++, что само по себе интересно, но так как изначально она была разработана для Spirit, она хорошо интегрирована и очень полезна, когда дело доходит до написания семантических действий. Я думаю, что использование усилителя / духа / включения / феникса ... заголовки будут в безопасности в будущем, так как мы, вероятно, перенаправим их на Boost. Заголовки Phoenix, как только они будут доступны.
Для выполнения нечувствительного к случаю разбора (с использованием<no_case
>) с таблицей символов (т.е. использовать парсер<symbols<>
>в директиве<no_case
>), эта таблица символов должна быть заполнена содержимым всех нижних регистров. Записи, содержащие один или несколько символов верхнего регистра, не будут соответствовать никаким входным данным.
Если вы используете Visual C++ и у вас есть такая ошибка:
error C2664: 'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const' :
cannot convert parameter 4 from '...' to '...'
Вы используете GCC и имеете такую ошибку, как:
error: no match for call to '(const boost::function<bool ()(...)>) (...)'
note: candidates are: ... boost::function4<R,T1,T2,T3,T4>::operator()(T0,T1,T2,T3) const [with ...]
Тогда эта запись в FAQ может помочь вам.
Определение правила или грамматики может содержать тип парсера пропуска. Если это так, это означает, что нетерминал может использоваться только с парсером пропуска совместимого типа. Вышеприведенная ошибка возникает, когда это не так, то есть:
- нетерминал, определенный типом парсера пропуска, используется без парсера пропуска; например, правило с типом парсера пропуска используется внутри директивы<
lexeme
>, или грамматика с типом парсера пропуска используется в<parse
>вместо<phrase_parse
>,
- или нетерминал используется с парсером пропуска несовместимого типа; например, правило, определенное одним типом парсера пропуска, вызывает второе правило, определенное с другим, несовместимым типом парсера пропуска.
![[Note]](/img/note.png) |
Note |
То же самое относится и кSpirit.Karma, заменив 'skip parser' и<lexeme >на 'delimit generator' и<verbatim >. Аналогично, соответствующие сообщения об ошибках вДухе. Кармассылка<boost::function3 >и 3-й параметр (вместо 4-го). |