Проблема авто-правила Boost Spirit - PullRequest
1 голос
/ 22 августа 2010

Я использую распространение атрибутов для построения синтаксического дерева для игрушечного языка.Я столкнулся с проблемой при определении моего оператора if, это трудно понять из сообщения об ошибке, но я думаю, что атрибут rhs не входит в ожидаемый атрибут.Это должно рухнуть до tuple <double,Statement,optional<Statement>> Я думаю.

Ошибка: C:\Program Files (x86)\CodeBlocks\MinGW\boost_1_43_0\boost\variant\variant.hpp|1293|error: no matching function for call to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list3<boost::recursive_wrapper<Lang::CompoundStatement>, boost::recursive_wrapper<Lang::IfStatement>, Lang::VarStatement> > >::initializer_node, mpl_::int_<1> >, boost::mpl::l_iter<boost::mpl::list2<boost::recursive_wrapper<Lang::IfStatemen [error cuts out here]

Спасибо.

PS Я не мог заставить код отображаться правильно, естьтекстовая версия здесь: http://freetexthost.com/a3smzx0zk5

PPS Некоторая информация, которую я забыл упомянуть.Это работает, если я удаляю "else" >> и меняю > statement на >> statement, но "else" >> statement должен свернуться до простого утверждения.Явное создание «else» как qi :: lit не помогает.

Ответы [ 2 ]

3 голосов
/ 23 августа 2010

Последовательность operator>>() и ожидание operator>() плохо сочетаются с точки зрения обработки атрибутов.Если вы используете оба оператора в одном выражении, общий атрибут не сгладится.Это произошло бы, если бы вы использовали только один или другой.

По этой причине атрибут, представленный выражением:

if_statement %= "if" > qi::double_ > statement >> -("else" > statement) ;

, равен:

tuple <tuple <double, Statement>, optional<Statement> >

который объясняет ваши проблемы компиляции.Переписав выражение следующим образом:

if_statement %= "if" > qi::double_ > statement > -("else" > statement) ;

должно решить проблему (без изменения семантики).

0 голосов
/ 27 августа 2010

Э-э, похоже, я не могу редактировать или комментировать, поэтому мне придется опубликовать это как ответ.

Я обошел проблему, разделив правило на правило оператора if и условие ifеще правило утверждения.Однако проблема снова в моем определении объявления init.
init_decl %= identifier >> -('=' >> expression) ;

identifier %= lexeme[(alpha | char_('<em>')) >> *(alnum | char</em>('_'))] ;

expression %= literal ;

literal %= real_literal | string_literal ;

real_literal %= double_ ;

string_literal %= lexeme['"' >> *(char_ - '"') >> '"'] ;

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

In member function 'void boost::variant::convert_construct(T&, int, mpl_::false_) [with T = const Lang::Elements::Expression, T0_ = double, T1 = std::basic_string, std::allocator >, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::vari

Вот этот метод:

template <typename T></p> <pre><code>void convert_construct( T& operand , int , mpl::false_ = mpl::false_() // is_foreign_variant ) { // NOTE TO USER : // Compile error here indicates that the given type is not // unambiguously convertible to one of the variant's types // (or that no conversion exists). // indicate_which( initializer::initialize( storage_.address() , operand ) ); }

Помните, что эта ошибка происходит от% = в выражении init_decl.Единственным вариантом в этом выражении является тот, который содержится в объекте Expression, который является значением атрибута правила выражения.Кажется, ошибка говорит о том, что вариант (тип объекта Expression содержит) пытается создать экземпляр себя из Expression, но я не вижу этого нигде в коде.Как бы то ни было, я добавил операторы приведения к структуре Expression, которая предоставляет базовый вариант, но все равно получил ошибку.

Метод, который вызывает метод выше, таков:*

Кажется, что вместо этого он пытается вызвать этот метод:

template

void convert_construct(
      Variant& operand
    , long
    , mpl::true_// is_foreign_variant
    )
{
    convert_copy_into visitor(storage_.address());
    indicate_which(
          operand.internal_apply_visitor(visitor)
        );
}</code>
</code>

Это недоразумение компилятора, которое является причиной этой ошибки?

...