C++ Boost.Spirit.Lex中的Phoenix占位符_val出错:(

C++ Boost.Spirit.Lex中的Phoenix占位符_val出错:(,c++,boost,boost-spirit,C++,Boost,Boost Spirit,我是Boost.Spirit.Lex的新手。 每次我尝试在我的简单lexer中的语义操作中使用lex::\u val时,都会出现一些奇怪的错误: #ifndef _TOKENS_H_ #define _TOKENS_H_ #include <iostream> #include <string> #include <boost/spirit/include/lex_lexertl.hpp> #include <boost/spirit/include/

我是Boost.Spirit.Lex的新手。 每次我尝试在我的简单lexer中的语义操作中使用lex::\u val时,都会出现一些奇怪的错误:

#ifndef _TOKENS_H_
#define _TOKENS_H_

#include <iostream>
#include <string>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_container.hpp>


namespace lex = boost::spirit::lex;
namespace phx = boost::phoenix;


enum tokenids 
{
    ID_IDENTIFICATOR = 1,
    ID_CONSTANT,
    ID_OPERATION,
    ID_BRACKET,
    ID_WHITESPACES
};

template <typename Lexer>
struct mega_tokens
    : lex::lexer<Lexer>
{

    mega_tokens()
        : identifier(L"[a-zA-Z_][a-zA-Z0-9_]*", ID_IDENTIFICATOR)
        , constant  (L"[0-9]+(\\.[0-9]+)?",     ID_CONSTANT     )
        , operation (L"[\\+\\-\\*/]",           ID_OPERATION    )
        , bracket   (L"[\\(\\)\\[\\]]",         ID_BRACKET      )
    {
        using lex::_tokenid;
        using lex::_val;
        using phx::val;

        this->self
                    = operation  [ std::wcout
                                       << val(L'<') << _tokenid
//                                     << val(L':') << lex::_val
                                       << val(L'>')
                                 ]
                    | identifier [ std::wcout
                                       << val(L'<') << _tokenid
                                       << val(L':') << _val
                                       << val(L'>')
                                 ]
                    | constant   [ std::wcout
                                       << val(L'<') << _tokenid
//                                     << val(L':') << _val
                                       << val(L'>')
                                 ]
                    | bracket    [ std::wcout
                                       << val(L'<') << _tokenid
//                                     << val(L':') << lex::_val
                                       << val(L'>')
                                 ]
            ;

    }

    lex::token_def<wchar_t,      wchar_t> operation;
    lex::token_def<std::wstring, wchar_t> identifier;
    lex::token_def<double,       wchar_t> constant;
    lex::token_def<wchar_t,      wchar_t> bracket;
};

#endif // _TOKENS_H_
\ifndef\u代币_
#定义标记_
#包括
#包括
#包括
#包括
#包括
#包括
名称空间lex=boost::spirit::lex;
名称空间phx=boost::phoenix;
枚举令牌ID
{
ID_标识符=1,
ID_常数,
ID_操作,
ID_括号,
ID_空格
};
模板
结构巨型令牌
:lex::lexer
{
mega_代币()
:标识符(L“[a-zA-Z_uz][a-zA-Z0-9_Z]*”,ID_标识符)
,常数(L“[0-9]+(\\.[0-9]+)?”,ID\u常数)
,操作(L“[\\+\-\*/]”,ID\U操作)
,括号(L“[\\(\\)\[\\]]”,ID\U括号)
{
使用lex::_tokenid;
使用lex::_val;
使用phx::val;
这个->自我
=操作[std::wcout

我认为这是当前Phoenix中与使用iostreams相关的问题。作为一种解决方法,我建议定义一个自定义(Phoenix)函数来执行实际输出:

struct output_operation_impl
{
    template <typename TokenId, typename Val>
    struct result { typedef void type; };

    template <typename TokenId, typename Val>
    void operator()(T1 const& tokenid, T2 const& val) const
    {
        std::wcout << L'<' << tokenid << L':' << val << L'>';
    }
};
boost::phoenix::function<output_operation_impl> const output_operation =
    output_operation_impl();

向Hartmut致意

谢谢,但一切都没有改变。我的Visual Studio 2008仍然打印出相同的错误。我对您的代码做了一些小的更正。也许,这是正确的:我已将所有代码放在一个文件中,并将其发布在此处:提前感谢。好的,看来您在Spirit.Lex中发现了一个错误。谢谢!我今天晚些时候会提交一个修复程序,谢谢o Boost SVN主干。直到最近,我一直希望这是我的错误。无论如何,谢谢你的帮助。这在Boost SVN中已修复。这不是Phoenix中的错误,而是Spirit.Lex中的错误。
struct output_operation_impl
{
    template <typename TokenId, typename Val>
    struct result { typedef void type; };

    template <typename TokenId, typename Val>
    void operator()(T1 const& tokenid, T2 const& val) const
    {
        std::wcout << L'<' << tokenid << L':' << val << L'>';
    }
};
boost::phoenix::function<output_operation_impl> const output_operation =
    output_operation_impl();
this->self = operation[ output_operation(_tokenid, _val) ] ... ;