C++ 令牌解析器语义动作

C++ 令牌解析器语义动作,c++,boost,boost-spirit,boost-bind,C++,Boost,Boost Spirit,Boost Bind,我已经基于上所示的代码编写了一个有效的令牌解析器 我的一条规则是这样的 set_name = ( tok.set_ >> tok.name_ >> tok.identifier ) [ std::cout << val("set name statement to: ") << _3 << "\n" ] ;

我已经基于上所示的代码编写了一个有效的令牌解析器

我的一条规则是这样的

    set_name 
        =   (   tok.set_ >> tok.name_ >> tok.identifier )
            [
                std::cout << val("set name statement to: ") << _3 << "\n"
            ]
        ;
它的输出和我期望的一样

将name语句设置为: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 )
            ]
        ;
类编写器
{
公众:
无效打印(字符串常量&s)常量
{
std::cout-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 1> C:\Program Files\boost\boost\U 1\U 44\boost/bind/bind.hpp(318):错误C2664:'R boost::_mfi::cmf1::operator()(const U&,A1)const':无法将参数2从'bool'转换为'const std::basic_string' 1> 与 1> [ 1> R=无效, 1> T=eCrew::rule::writer, 1> A1=常量标准::字符串&, 1> U=eCrew::规则::编写器* 1> ] 1> 及 1> [ 1> _Elem=char, 1> _Traits=std::char_Traits, 1> _Ax=std::分配器 1> ] 1> 原因:无法从“bool”转换为“const std::string” 1> 没有构造函数可以采用源类型,或者构造函数重载解析不明确 为什么编译器抱怨a试图从bool转换为字符串?我看不到bool。

中的占位符

std::cout << val("set name statement to: ") << _3 << "\n"
boost::bind(&writer::print, &w, ::_3)
是boost.bind占位符(自然)

这些占位符不会共享相同的行为,甚至引用相同的数据。形式为的Phoenix占位符引用解析器的第N个子属性,而绑定占位符具有不同的含义:

  • _1作为一个整体引用解析器的属性
  • _2表示解析器的上下文
  • _3指的是一个
    bool&
    “hit”参数
在您的情况下,最简单的解决方案是使用
boost::phoenix::bind
而不是
boost::bind
,这样您就可以继续使用
\u3
引用解析器的第三个子属性,而不必在
writer::print
中手动选择它

或者,只将语义操作附加到
tok.identifier
,这样boost.bind的
:\u 1
就可以正常工作:

set_name
  = tok.set_
    >> tok.name_
    >> tok.identifier[boost::bind(&writer::print, &w, ::_1)]
;

在…中,w是否被重新声明为bool?如果为writer使用更唯一的变量名会发生什么情况?@jon将“w”更改为“the_writer”。结果相同。这听起来是个好主意。我会尝试一下,然后再与您联系。
set_name
  = tok.set_
    >> tok.name_
    >> tok.identifier[boost::bind(&writer::print, &w, ::_1)]
;