我正在尝试解析这种类型的字符串
1.2e3ex
1.2e3 ex
并设置好
x3::float_ >> "ex"
不幸的是,这无法解析
1ex
完整的示例代码:
#include <iostream>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
const auto parser = x3::float_ >> "em";
int main()
{
std::string input = "1em";
auto first = input.begin();
auto last = input.end();
float value{};
bool result = x3::phrase_parse(first, last, parser, x3::blank, value);
if(result)
{
if(first == last)
std::cout << "parse succesful: " << value << '\n';
else
std::cout << "incomplete parse: " << value << '\n';
}
else
std::cout << "parse unsuccesful\n";
}
似乎我需要跳过一些箍,
struct non_scientific_float_policy : x3::real_policies<float>
{
template <typename Iterator>
static bool parse_exp(Iterator& first, Iterator const& last)
{
return false;
}
};
const auto non_scientific_float = x3::real_parser<float, non_scientific_float_policy>{};
const auto parser = non_scientific_float >> "em" | x3::float_ >> "em";
还有别的办法吗?
答案 0 :(得分:4)
您可以通过调整实际策略parse_exp
来解决此问题,以使指数检测不仅需要[eE]
字符,而且还需要[eE][-+]?[0-9]
。
#include <iostream>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
template <typename T>
struct alt_real_policies : x3::real_policies<T>
{
template <typename Iterator>
static bool parse_exp(Iterator& first, Iterator const& last)
{
Iterator save = first;
if (x3::real_policies<T>::parse_exp(first, last)) {
Iterator iter = first;
if (x3::extract_int<x3::unused_type, 10, 1, 1>::call(iter, last, x3::unused))
return true;
}
first = save;
return false;
}
};
const x3::real_parser<float, alt_real_policies<float>> altfloat;
const auto parser = altfloat >> "em";
int main()
{
std::string input = "1em";
auto first = input.begin();
auto last = input.end();
float value{};
bool result = x3::phrase_parse(first, last, parser, x3::blank, value);
if (result)
{
if (first == last)
std::cout << "parse succesful: " << value << '\n';
else
std::cout << "incomplete parse: " << value << '\n';
}
else
std::cout << "parse unsuccesful\n";
}
答案 1 :(得分:0)
您可以将替代策略用于指数的非贪婪解析。我能想到的最简单的是:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
template <typename T>
struct no_exponent : x3::real_policies<T> {
template <typename It>
static bool parse_exp(It, It) { return false; }
};
x3::real_parser<double, no_exponent<double> > noexp_;
const auto parser = (x3::float_ | noexp_) >> "em";
int main() {
std::string input = "-1.67em";
auto first = input.begin();
auto last = input.end();
float value{};
bool result = x3::phrase_parse(first, last, parser, x3::blank, value);
if (result) {
if (first == last)
std::cout << "parse succesful: " << value << '\n';
else
std::cout << "incomplete parse: " << value << '\n';
} else
{
std::cout << "parse unsuccesful\n";
}
}
打印:
parse succesful: -1.67