gpt4 book ai didi

c++ - 使用 Boost.Spirit.Lex 和 Boost.Spirit.Qi 解析 "true"和 "false"

转载 作者:太空狗 更新时间:2023-10-29 21:29:32 26 4
gpt4 key购买 nike

作为使用 Boost.Spirit 的更大语法的第一阶段,我尝试解析“true”和“false”以生成相应的 bool 值,truefalse.

我正在使用 Spirit.Lex 对输入进行标记化,并为整数和浮点文字(包括那些以宽松的科学记数法表示的文字)提供了一个有效的实现,公开了 intfloat 属性。

token 定义

#include <boost/spirit/include/lex_lexertl.hpp>

namespace lex = boost::spirit::lex;

typedef boost::mpl::vector<int, float, bool> token_value_type;

template <typename Lexer>
struct basic_literal_tokens : lex::lexer<Lexer> {
basic_literal_tokens() {
this->self.add_pattern("INT", "[-+]?[0-9]+");
int_literal = "{INT}";
// To be lexed as a float a numeric literal must have a decimal point
// or include an exponent, otherwise it will be considered an integer.
float_literal = "{INT}(((\\.[0-9]+)([eE]{INT})?)|([eE]{INT}))";

literal_true = "true";
literal_false = "false";
this->self = literal_true | literal_false | float_literal | int_literal;
}

lex::token_def<int> int_literal;
lex::token_def<float> float_literal;
lex::token_def<bool> literal_true, literal_false;
};

测试浮点文字的解析

我的实际实现使用 Boost.Test,但这是一个独立的示例。

#include <string>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <limits>

bool parse_and_check_float(std::string const & input, float expected) {
typedef std::string::const_iterator base_iterator_type;
typedef lex::lexertl::token<base_iterator_type,
token_value_type
> token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;

basic_literal_tokens<lexer_type> basic_literal_lexer;
base_iterator_type input_iter(input.begin());

float actual;

bool result = lex::tokenize_and_parse(input_iter, input.end(),
basic_literal_lexer,
basic_literal_lexer.float_literal,
actual);
return result && std::abs(expected - actual) < std::numeric_limits<float>::epsilon();
}

int main(int argc, char *argv[]) {
if (parse_and_check_float("+31.4e-1", 3.14)) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
}

解析“真”和“假”

我的问题是在尝试解析“true”和“false”时。这是我正在使用的测试代码(删除 Boost.Test 部分后):

bool parse_and_check_bool(std::string const & input, bool expected) {
typedef std::string::const_iterator base_iterator_type;
typedef lex::lexertl::token<base_iterator_type,
token_value_type
> token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;

basic_literal_tokens<lexer_type> basic_literal_lexer;
base_iterator_type input_iter(input.begin());

bool actual;
lex::token_def<bool> parser = expected ? basic_literal_lexer.literal_true
: basic_literal_lexer.literal_false;
bool result = lex::tokenize_and_parse(input_iter, input.end(),
basic_literal_lexer, parser,
actual);
return result && actual == expected;
}

但编译失败:

boost/spirit/home/qi/detail/assign_to.hpp: In function ‘void boost::spirit::traits::assign_to(const Iterator&, const Iterator&, Attribute&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Attribute = bool]’:
boost/spirit/home/lex/lexer/lexertl/token.hpp:434: instantiated from ‘static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, boost::spirit::lex::lexertl::token<Iterator, AttributeTypes, HasState>, void>::call(const boost::spirit::lex::lexertl::token<Iterator, AttributeTypes, HasState>&, Attribute&) [with Attribute = bool, Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, AttributeTypes = boost::mpl::vector<int, float, bool, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, HasState = mpl_::bool_<true>]’

... backtrace of instantiation points ....

boost/spirit/home/qi/detail/assign_to.hpp:79: error: no matching function for call to ‘boost::spirit::traits::assign_to_attribute_from_iterators<bool, __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, void>::call(const __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, const __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, bool&)’
boost/spirit/home/qi/detail/construct.hpp:64: note: candidates are: static void boost::spirit::traits::assign_to_attribute_from_iterators<bool, Iterator, void>::call(const Iterator&, const Iterator&, char&) [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]

我对此的解释是 Spirit.Qi 不知道如何将字符串转换为 bool 值——当然不是这样?以前有其他人这样做过吗?如果是,怎么办?

最佳答案

你想要类似的东西

qi::rule<Iterator, bool> true_false_parser;
a = qi::lexeme[ qi::no_case[ qi::eps > ( qi::lit("true")[ _val=true] | qi::lit("false")[ _val=false] ) ] ];

这将抛出当且仅当 token 不是“真”或“假”

默认false做

qi::rule<Iterator, bool> true_false_parser;
a = qi::lexeme[ qi::no_case[ ( qi::lit("true")[ _val=true] ) | (*qi::char_)[_val=false] ] ];

关于c++ - 使用 Boost.Spirit.Lex 和 Boost.Spirit.Qi 解析 "true"和 "false",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4643926/

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