gpt4 book ai didi

c++ - Boost.Spirit.Lex :( 中 Phoenix 占位符 _val 出错

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:13:37 26 4
gpt4 key购买 nike

我是 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 header “boost/spirit/home/lex/argument.hpp”中出现错误:

return: can't convert 'const boost::variant' to 'boost::variant &'

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

显然,我以错误的方式使用了 _val,但我不知道如何正确地使用它。请帮助! :)

附言对不起我糟糕的英语……

最佳答案

我相信这是当前 Phoenix 中与使用 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) ] ... ;

问候哈特穆特

关于c++ - Boost.Spirit.Lex :( 中 Phoenix 占位符 _val 出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2890635/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com