凤凰占位符_val在Boost.Spirit.Lex中出错:(

时间:2010-05-23 03:57:52

标签: c++ boost boost-spirit

我是Boost.Spirit.Lex的新手。 每次我尝试在我的简单词法分析器中的语义操作中使用lex :: _ 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_

#include <cstdlib>
#include <iostream>
#include <locale>
#include <boost/spirit/include/lex_lexertl.hpp>

#include "tokens.h"

int main()
{
    setlocale(LC_ALL, "Russian");

    namespace lex = boost::spirit::lex;

    typedef std::wstring::iterator base_iterator;
    typedef lex::lexertl::token <
        base_iterator,
        boost::mpl::vector<wchar_t, std::wstring, double, wchar_t>,
        boost::mpl::true_
    > token_type;
    typedef lex::lexertl::actor_lexer<token_type> lexer_type;
    typedef mega_tokens<lexer_type>::iterator_type iterator_type;

    mega_tokens<lexer_type> mega_lexer;

    std::wstring str = L"alfa+x1*(2.836-x2[i])";
    base_iterator first = str.begin();

    bool r = lex::tokenize(first, str.end(), mega_lexer);

    if (r) {
        std::wcout << L"Success" << std::endl;
    }
    else {
        std::wstring rest(first, str.end());
        std::wcerr << L"Lexical analysis failed\n" << L"stopped at: \"" 
            << rest << L"\"\n";
    }

    return EXIT_SUCCESS;
}

此代码在编译时在第167行的Boost标题'boost / spirit / home / lex / argument.hpp'中导致错误:

  

返回:无法转换'const   boost :: variant'改为   'boost :: variant&amp;'

当我不使用lex :: _ val程序编译时没有错误。

显然,我以错误的方式使用_val,但我不知道如何正确地执行此操作。请帮忙! :)

P.S。对不起我可怕的英语......

1 个答案:

答案 0 :(得分:2)

我认为这是当前凤凰城与使用iostream相关的一个问题。作为一种解决方法,我建议定义一个执行实际输出的自定义(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();

将其称为:

this->self = operation[ output_operation(_tokenid, _val) ] ... ;

关心哈特穆特

相关问题