令牌解析器语义动作

时间:2011-03-29 20:30:10

标签: c++ boost boost-spirit boost-bind

我根据spirit lex example 4

中显示的代码编写了一个工作令牌解析器

我的一条规则看起来像这样

    set_name 
        =   (   tok.set_ >> tok.name_ >> tok.identifier )
            [
                std::cout << val("set name statement to: ") << _3 << "\n"
            ]
        ;

这很有效。出现时

SET NAME xyz

按预期输出

  

将name statement设置为:xyz

现在我想做一些有用的事情,将找到的名字存储在一个类中。在parser semantic examples工作我写了这段代码

  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转换为字符串?我看不到布尔。

1 个答案:

答案 0 :(得分:3)

中的占位符
std::cout << val("set name statement to: ") << _3 << "\n"

指的是boost::spirit::_3,它是一个boost.phoenix v2占位符。

中的占位符
boost::bind(&writer::print, &w, ::_3)

是一个boost.bind占位符(当然)。

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

  • _1指整个解析器的属性
  • _2指的是解析器的上下文
  • _3指的是bool&'点'参数

在您的情况下,最简单的解决方案是使用boost::phoenix::bind而不是boost::bind,以便您可以继续使用_3来引用解析器的第三个子属性,而不必选择它在writer::print内手动输出。

或者,只将语义操作附加到tok.identifier,以便boost.bind的::_1按预期工作:

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