Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我能';无法获取令牌的字符串值_C++_Boost_Boost Spirit_Boost Spirit Lex - Fatal编程技术网

C++ 我能';无法获取令牌的字符串值

C++ 我能';无法获取令牌的字符串值,c++,boost,boost-spirit,boost-spirit-lex,C++,Boost,Boost Spirit,Boost Spirit Lex,我试图用Boost Spirit为一种小编程语言实现一个Lexer 我必须获取令牌的值,但我得到了一个错误的\u get异常: 在抛出“boost::bad_get”实例后调用terminate what():boost::bad\u get:使用boost::get中止获取值失败 我在执行以下操作时获得此异常: std::string contents = "void"; base_iterator_type first = contents.begin(); base_iterator_t

我试图用Boost Spirit为一种小编程语言实现一个Lexer

我必须获取令牌的值,但我得到了一个错误的\u get异常:

在抛出“boost::bad_get”实例后调用terminate
what():boost::bad\u get:使用boost::get中止获取值失败

我在执行以下操作时获得此异常:

std::string contents = "void";

base_iterator_type first = contents.begin();
base_iterator_type last = contents.end();

SimpleLexer<lexer_type> lexer;

iter = lexer.begin(first, last);
end = lexer.end();

std::cout << "Value = " << boost::get<std::string>(iter->value()) << std::endl;
std::string contents=“void”;
base_iterator_type first=contents.begin();
base_iterator_type last=contents.end();
SimpleLexer-lexer;
iter=lexer.begin(第一个,最后一个);
end=lexer.end();
std::cout self+=关键字|关键字|关键字|关键字|真|关键字|假|关键字|如果|关键字|其他|关键字|从|关键字|到|关键字| foreach;
这个->self+=整数| literal |字;
这->自我+=等于|不|等于|更大|等于|更少|更大|更少;
这个->self+=左|右|左|右|左|右|大括号;
这->自我+=逗号|停止;
这个->self+=赋值|交换|加|减|乘|除|模;
//忽略空白和注释
这->self+=空白[lex::_pass=lex::pass\u flags::pass\u ignore];
这->self+=注释[lex::\u pass=lex::pass\u flags::pass\u ignore];
}
lex::token_def word,literal,integer;
lex::token_def left_parenth,right_parenth,left_大括号,right_大括号;
lex::token_def stop,逗号;
标记定义赋值、交换、加法、减法、乘法、除法、模;
lex::token_def equals,not_equals,greater,less,greater_equals,less_equals;
//关键词
lex::token_def keyword_if、keyword_else、keyword_for、keyword_while、keyword_from、keyword_to、keyword_foreach;
lex::token_def keyword_true,keyword_false;
//忽略标记
lex::token_def空格;
lex::token_def注释;
};

是否有其他方法获取令牌的值?

您始终可以使用“默认”令牌数据(这是源迭代器类型的迭代器范围)

在研究了boost存储库中的测试用例之后,我发现了一些事情:

  • 这是故意的
  • 有一个更简单的方法
  • 在Lex语义操作中(例如使用_1)和在Qi中使用lexer标记时,更容易实现自动化;分配将自动转换为Qi属性类型
  • 这(确实)得到了文档中提到的“惰性、一次性、评估”语义
关键是令牌数据是变量,它以原始输入迭代器范围开始。只有在“a”强制赋值之后,转换的属性才会缓存在变量中。您可以见证这种转变:

lexer_type::iterator_type iter = lexer.begin(first, last);
lexer_type::iterator_type end = lexer.end();

assert(0 == iter->value().which());
std::cout << "Value = " << boost::get<boost::iterator_range<base_iterator_type> >(iter->value()) << std::endl;

std::string s;
boost::spirit::traits::assign_to(*iter, s);
assert(1 == iter->value().which());
std::cout << "Value = " << s << std::endl;

看起来有点太复杂了,应该由精神来完成。在我的例子中,标记的类型化是为了获取它们的值,因此我从value()中获取变量,而不是直接从迭代器中获取变量。我还有一个int标记。使用您的技术,您不会利用value()提供的变量,否?哪一部分过于复杂?它所说的
std::string(iter->value().begin(),iter->value().end())
?我没有把它说清楚(你希望我们读入你的长篇样本来“理解”你的意思,你也不想读7行
showtoken
来了解它是如何完成的?嗯。)我的样本可能看起来过于复杂了,因为它是一个完整的例子,说明了如何在现实生活中的解析器中使用它来实现,例如错误报告。很抱歉展示了你不感兴趣的东西:)我发现过于复杂的事情是,我们用手解析精神给予我们的东西。如果我有float、int、string和bool标记,我想得到它们的基本值,我必须创建4个解析函数,不是吗?通常这些值存储在boost::variant中。或者我不理解value()函数的返回值。我怀疑您可能误解了Lexer的用法。Lexer解析为标记(根据定义,这些标记只是源迭代器范围)。如果你想要简单而自动的值提取,可以使用灵气(当然,Lexer令牌可以提供给您。将在一点时间内更新答案。我已经计算出了进行求值的条件。我希望这些信息有帮助。再次阅读时,我注意到您指定
lex::omit
作为令牌属性类型。这些令牌不会公开任何值数据(甚至不会公开迭代器对)。这可能是你的问题。否则,我衷心建议在令牌迭代器之上使用Qi进行解析:充分利用这两个方面。我验证了这一点,但遗憾的是,这不是问题所在。我只使用boost::get对一个类型良好且应该具有值的令牌进行解析。
std::string tokenvalue(iter->value().begin(), iter->value().end());
lexer_type::iterator_type iter = lexer.begin(first, last);
lexer_type::iterator_type end = lexer.end();

assert(0 == iter->value().which());
std::cout << "Value = " << boost::get<boost::iterator_range<base_iterator_type> >(iter->value()) << std::endl;

std::string s;
boost::spirit::traits::assign_to(*iter, s);
assert(1 == iter->value().which());
std::cout << "Value = " << s << std::endl;
#include <boost/spirit/include/lex_lexertl.hpp>

#include <iostream>
#include <string>

namespace lex = boost::spirit::lex;

typedef std::string::iterator base_iterator_type;
typedef boost::spirit::lex::lexertl::token<base_iterator_type, boost::mpl::vector<int, std::string>> Tok;
typedef lex::lexertl::actor_lexer<Tok> lexer_type;

template<typename L>
class SimpleLexer : public lex::lexer<L> {
    private:

    public:
        SimpleLexer() {
            word = "[a-zA-Z]+";
            integer = "[0-9]+";
            literal = "...";

            this->self += integer | literal | word;
        }

        lex::token_def<std::string> word, literal;
        lex::token_def<int> integer;
};

int main(int argc, const char* argv[]) {
    SimpleLexer<lexer_type> lexer;

    std::string contents = "void";

    base_iterator_type first = contents.begin();
    base_iterator_type last = contents.end();

    lexer_type::iterator_type iter = lexer.begin(first, last);
    lexer_type::iterator_type end = lexer.end();

    assert(0 == iter->value().which());
    std::cout << "Value = " << boost::get<boost::iterator_range<base_iterator_type> >(iter->value()) << std::endl;

    std::string s;
    boost::spirit::traits::assign_to(*iter, s);
    assert(2 == iter->value().which());
    std::cout << "Value = " << s << std::endl;

    return 0;
}