C
C
cunion2021-08-05 14:19:54
C++ / C#
cunion, 2021-08-05 14:19:54

Why does the parser on Boost.Spirit incorrectly parse a negative fraction?

Decided to write a JSON parser. Everything works fine, but if you pass a negative fraction as a value, the parser breaks.

Parser code

struct nullptr_t : qi::symbols<char, void*>
  {
    nullptr_t()
    {
      add
      ("null", nullptr)
      ;
    }
  } nullptr_;

  using json = std::map<std::string, std::any>;
  using json_node = std::pair<std::string, std::any>;

  template <class Iterator>
  struct json_grammar : qi::grammar<Iterator, json(), qi::space_type>
  {
    json_grammar() : json_grammar::base_type(start)
    {
      start = dictionary.alias();

      quoted_string = 
        '\"' >> 
        +(qi::char_ - '\"') [qi::_val += qi::_1] 
        >> '\"';

      dictionary =
        '{' >>
        node [phoenix::insert(qi::_val, qi::_1)] % ','
        >> '}';

      array =
        '[' >>
        value [phoenix::push_back(qi::_val, qi::_1)] % ','
        >> ']';

      value = quoted_string | dictionary | array | nullptr_ | qi::int_ | qi::double_ | qi::bool_;
      node = quoted_string >> ':' >> value;
    }

    qi::rule<Iterator, json(), qi::space_type> start;
    qi::rule<Iterator, std::string(), qi::space_type> quoted_string;

    qi::rule<Iterator, json(), qi::space_type> dictionary;
    qi::rule<Iterator, std::vector<std::any>(), qi::space_type> array;

    qi::rule<Iterator, std::any(), qi::space_type> value;
    qi::rule<Iterator, std::pair<std::string, std::any>(), qi::space_type> node;
  };

Answer the question

In order to leave comments, you need to log in

1 answer(s)
C
cunion, 2021-08-05
@0hquazEd

Solved a problem. Removed qi::int_from value. When the parser saw a negative number, he took it for qi::int_and, when meeting with a fractional part, threw an error.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question