令牌解析器语义动作
我已经根据 spirit lex 示例 4
我的规则之一如下所示
set_name
= ( tok.set_ >> tok.name_ >> tok.identifier )
[
std::cout << val("set name statement to: ") << _3 << "\n"
]
;
这效果很好。当呈现
SET NAME xyz
它时,输出如我所料
将名称语句设置为:xyz
现在我想做一些有用的事情,将找到的名称存储到一个类中。使用 解析器语义示例 我编写了这段代码,
class writer
{
public:
void print(string const& s) const
{
std::cout << s << std::endl;
}
};
writer w;
...
set_name
= ( tok.set_ >> tok.name_ >> tok.identifier )
[
boost::bind( &writer::print, &w, ::_3 )
]
;
但它无法编译。
1>C:\Program Files\boost\boost_1_44\boost/bind/bind.hpp(318) : error C2664: 'R boost::_mfi::cmf1::operator ()(const U &,A1) const' : cannot convert parameter 2 from 'bool' to 'const std::basic_string ' 1> with 1> [ 1> R=void, 1> T=eCrew::rule::writer, 1> A1=const std::string &, 1> U=eCrew::rule::writer * 1> ] 1> and 1> [ 1> _Elem=char, 1> _Traits=std::char_traits, 1> _Ax=std::allocator 1> ] 1> Reason: cannot convert from 'bool' to 'const std::string' 1> No constructor could take the source type, or constructor overload resolution was ambiguous
为什么编译器会抱怨尝试从 bool 转换为 string?我看不到任何布尔值。
I have written a working token parser based on the code shown at spirit lex example 4
One of my rules looks like this
set_name
= ( tok.set_ >> tok.name_ >> tok.identifier )
[
std::cout << val("set name statement to: ") << _3 << "\n"
]
;
This works well. When presented with
SET NAME xyz
it outputs as I expect
set name statement to: xyz
Now I want to do something useful, store the name found into a class. Working from parser semantic examples I write this code
class writer
{
public:
void print(string const& s) const
{
std::cout << s << std::endl;
}
};
writer w;
...
set_name
= ( tok.set_ >> tok.name_ >> tok.identifier )
[
boost::bind( &writer::print, &w, ::_3 )
]
;
This does not compile
1>C:\Program Files\boost\boost_1_44\boost/bind/bind.hpp(318) : error C2664: 'R boost::_mfi::cmf1::operator ()(const U &,A1) const' : cannot convert parameter 2 from 'bool' to 'const std::basic_string ' 1> with 1> [ 1> R=void, 1> T=eCrew::rule::writer, 1> A1=const std::string &, 1> U=eCrew::rule::writer * 1> ] 1> and 1> [ 1> _Elem=char, 1> _Traits=std::char_traits, 1> _Ax=std::allocator 1> ] 1> Reason: cannot convert from 'bool' to 'const std::string' 1> No constructor could take the source type, or constructor overload resolution was ambiguous
Why is the compiler complaining about a trying to convert from bool to string? There is no bool that I can see.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
中的占位
符指的是
boost::spirit::_3
,它是一个 boost.phoenix v2 占位符。中的占位符是 boost.bind 占位符(自然)。
这些占位符不具有相同的行为,甚至引用相同的数据。 _N 形式的 Phoenix 占位符指的是解析器的第 N 个子属性,而绑定占位符具有不同的含义:
bool&
'hit' 参数您的情况最简单的解决方案是使用
boost::phoenix::bind
而不是boost::bind
,这样您就可以继续使用_3
来引用解析器的第三个子属性,而不必在writer::print
内部手动挑选它。或者,仅将语义操作附加到
tok.identifier
,以便 boost.bind 的::_1
按您的预期工作:The placeholder in
refers to
boost::spirit::_3
, which is a boost.phoenix v2 placeholder. The placeholder inis a boost.bind placeholder (naturally).
These placeholders do not share the same behavior, or even refer to the same data. Phoenix placeholders of the form _N refer to the Nth subattribute of your parser, while bind placeholders have a different meaning:
bool&
'hit' parameterThe easiest solution in your case is to use
boost::phoenix::bind
instead ofboost::bind
, so that you can continue using_3
to refer to the third subattribute of your parser instead of having to pick it out manually inside ofwriter::print
.Alternatively, only attach the semantic action to
tok.identifier
so that boost.bind's::_1
works as you expect: