【发布时间】:2019-03-01 20:49:23
【问题描述】:
我有一个 boost::spirit 解析器,它应该简单地分配一个指向其属性的指针:
rule<CompoundExpression *(Scope &)> var_ref = var<CompoundExpression>()(_r1) [
_val = new_<Reference<Variable<CompoundExpression>>>(_1)
];
其中var<CompoundExpression>() 是一个公正的函数,它返回对执行实际解析的静态规则的引用。我在整个代码中对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 的类型定义为gologpp::CompoundExpression
现在,如果我没看错的话,result_of::is_nullary (/usr/include/boost/phoenix/core/is_nullary.hpp:115) 的基本类型恰好是一个引用类型,这就是问题所在。我的 Reference<Variable<CompoundExpression>> 类型看起来非常好,我可以从中构造对象,也可以按照我的预期使用它。
问题似乎还在于整个 phoenix 赋值表达式,而不是它的 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,这不应该发生。但是为什么会这样?我怎么会导致呢?
【问题讨论】:
-
顺便说一句,我知道我不应该在精神动作中使用
new_,但我需要多态性,所以为了简单起见,我在这里妥协。 -
你也不应该从函数中返回规则,主要是。但是我们没有相关代码来查看实际问题是什么。尝试制作 SSCCE/MVCE
-
是来自github.com/MASKOR/gologpp/tree/master/src/parser 吗?如果有,哪个版本有问题?
-
它不在github上,但我现在已经推送了:github.com/MASKOR/gologpp/tree/vmatare/composite_types
-
哦,我想我找到了。我有一种预感,这很愚蠢。看起来我忘记了标题一侧的包含。但是由此产生的错误消息很有可能让人困惑......
标签: c++ boost boost-spirit boost-phoenix