Разбор числа с плавающей запятой, за которым следует строка, содержащая символ «е» - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь проанализировать этот тип строки

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";
}

Доступен в прямом эфире на Coliru .

Кажется, мне нужно прыгнуть через несколько обручей,

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";

Нет другого пути?

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Вы можете решить эту проблему, настроив реальную политику 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";
}

http://coliru.stacked-crooked.com/a/f60f334c960cb602

0 голосов
/ 02 февраля 2019

Вы можете использовать альтернативную политику для не жадного анализа показателя.Самое простое, о чем я могу подумать:

Live On Coliru

#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
...