У меня есть boost::spirit
парсер, который должен просто назначить указатель на его атрибут:
rule<CompoundExpression *(Scope &)> var_ref = var<CompoundExpression>()(_r1) [
_val = new_<Reference<Variable<CompoundExpression>>>(_1)
];
, где var<CompoundExpression>()
- это функция just, которая возвращает ссылку на статическое правило, которое выполняетфактический разбор.Я использую одно и то же действие присваивания с другими экземплярами шаблона Reference<Variable<T>>
по всему коду, и это нормально, за исключением того, который использует параметр CompoundExpression
.
Буквальная ошибка GCC такова:
In file included from /usr/include/boost/phoenix/core/actor.hpp:20,
from /usr/include/boost/phoenix/core.hpp:12,
from /usr/include/boost/spirit/include/phoenix_core.hpp:11,
from /usr/include/boost/spirit/home/support/argument.hpp:18,
from /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:29,
from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14,
from /usr/include/boost/spirit/include/qi_nonterminal.hpp:16,
from /home/ich/sync/ConTrAkt/gologpp/src/parser/utilities.h:7,
from /home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.h:4,
from /home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.cpp:1:
/usr/include/boost/phoenix/core/is_nullary.hpp: In instantiation of ‘struct boost::phoenix::result_of::is_nullary<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>, void>’:
/usr/include/boost/phoenix/core/actor.hpp:178:13: required from ‘struct boost::phoenix::result_of::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >’
/usr/include/boost/phoenix/core/actor.hpp:271:9: required from ‘struct boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >’
/home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.cpp:22:58: required from here
/usr/include/boost/phoenix/core/is_nullary.hpp:115:16: error: base type ‘boost::phoenix::evaluator::impl<const boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>&, boost::phoenix::vector2<mpl_::bool_<true>, boost::phoenix::is_nullary>, boost::proto::envns_::empty_env>::result_type’ {aka ‘const boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>&’} fails to be a struct or class type
struct is_nullary
^~~~~~~~~~
Поскольку это практически нечитаемо, я постараюсь clang-format
.Итак, я думаю, что это сводится к последней строке:
/usr/include/boost/phoenix/core/is_nullary.hpp:115:16: error: base type
‘boost::phoenix::evaluator::impl<
const boost::proto::exprns_::basic_expr<
boost::proto::tagns_::tag::assign,
boost::proto::argsns_::list2<
boost::proto::exprns_::expr<
boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::spirit::attribute<0>>, 0>,
boost::phoenix::actor<boost::proto::exprns_::basic_expr<
boost::phoenix::tag::new_,
boost::proto::argsns_::list2<
boost::proto::exprns_::basic_expr<
boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<
boost::phoenix::detail::target<gologpp::Reference<
gologpp::Variable<gologpp::TypedExpression<
gologpp::CompoundType>>>>>,
0>,
boost::phoenix::actor<boost::spirit::argument<0>>>,
2>>>,
2> &,
boost::phoenix::vector2<mpl_::bool_<true>, boost::phoenix::is_nullary>,
boost::proto::envns_::empty_env>::result_type’ {
aka ‘const boost::proto::exprns_::basic_expr<
boost::proto::tagns_::tag::assign,
boost::proto::argsns_::list2<
boost::proto::exprns_::expr<
boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::spirit::attribute<0>>, 0>,
boost::phoenix::actor<boost::proto::exprns_::basic_expr<
boost::phoenix::tag::new_,
boost::proto::argsns_::list2<
boost::proto::exprns_::basic_expr<
boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<
boost::phoenix::detail::target<gologpp::Reference<
gologpp::Variable<gologpp::TypedExpression<
gologpp::CompoundType>>>>>,
0>,
boost::phoenix::actor<boost::spirit::argument<0>>>,
2>>>,
2> &’}
fails to be a struct or class type
Обратите внимание, что gologpp::TypedExpression<gologpp::CompoundType
typedef'd как gologpp::CompoundExpression
Теперь, если я правильно читаю, эта базатип result_of::is_nullary
(/usr/include/boost/phoenix/core/is_nullary.hpp:115) так или иначе является ссылочным типом, и в этом проблема.Мой тип Reference<Variable<CompoundExpression>>
выглядит отлично, я могу создавать объекты из него и использовать его так, как я ожидал.Также проблема, по-видимому, связана со всем выражением присваивания феникса, а не с его LHS или RHS.
Глядя на boost / phoenix / core / is_nullary.hpp: 115:
struct is_nullary
: boost::phoenix::evaluator::impl<
Expr const &
, vector2<
mpl::true_
, boost::phoenix::is_nullary
>
, proto::empty_env
>::result_type
{};
Кажется, что каким-то образом Expr const &
(который в моем случае является выражением присваивания) становится result_type
, чего не должно быть.Но тогда почему и как я мог это вызывать?