Opened 9 years ago

Closed 5 years ago

#9613 closed Bugs (fixed)

Cannot return parse result as a class using boost::spirit::qi

Reported by: ovydew@… Owned by: Joel de Guzman
Milestone: To Be Determined Component: spirit
Version: Boost 1.55.0 Severity: Problem
Keywords: spirit, qi, parsing, class, adapt Cc:

Description

Good day!

I went through the Spirit tutorials (Boost documentation), chose the "Employee" example (http://www.boost.org/doc/libs/1_55_0/libs/spirit/example/qi/employee.cpp) and wanted to return the result of parsing using a class rather than a struct. When just changing from a struct to a class and adding the "public" visibility modifier everything works fine. However when using BOOST_FUSION_ADAPT_ADT, private fields and getters and setters I am receiving compile errors (Source code: below).

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/adapted/adt/adapt_adt.hpp>
#include <boost/fusion/include/adapt_adt.hpp>

#include <iostream>
#include <string>
#include <complex>

namespace client
{
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

    class employee
    {

        private:

            int age;
            std::string surname;
            std::string forename;
            double salary;

        public:

            int getAge() const {
                return age;
            }

            void setAge(int age) {
                this->age = age;
            }

            const std::string &getSurname() const {
                return surname;
            }

            void setSurname(const std::string &surname) {
                this->surname = surname;
            }

            const std::string &getForename() const {
                return surname;
            }

            void setForename(const std::string &forename) {
                this->forename = forename;
            }

            double getSalary() const {
                return salary;
            }

            void setSalary(double salary) {
                this->salary = salary;
            }
    };
    
}

BOOST_FUSION_ADAPT_ADT(
    client::employee,
    (int, int, obj.getAge(), obj.setAge(val))
    (const std::string &, const std::string &, obj.getSurname(), obj.setSurname(val))
    (const std::string &, const std::string &, obj.getForename(), obj.setForename(val))
    (double, double, obj.getSalary(), obj.setSalary(val))
)

namespace client
{
    template <typename Iterator>
    struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>
    {
        employee_parser() : employee_parser::base_type(start)
        {
            using qi::int_;
            using qi::lit;
            using qi::double_;
            using qi::lexeme;
            using ascii::char_;

            quoted_string = lexeme['"' >> +(char_ - '"') >> '"'];

            start =
                lit("employee")
                >> '{'
                >>  int_ >> ','
                >>  quoted_string >> ','
                >>  quoted_string >> ','
                >>  double_
                >>  '}'
                ;
        }

        qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
        qi::rule<Iterator, employee(), ascii::space_type> start;
    };
}

int
main()
{
    std::cout
        << "Give me an employee of the form :"
        << "employee{age, \"surname\", \"forename\", salary } \n";

    using boost::spirit::ascii::space;
    typedef std::string::const_iterator iterator_type;
    typedef client::employee_parser<iterator_type> employee_parser;

    employee_parser g;
    std::string str;
    getline(std::cin, str);
   
    client::employee emp;
    std::string::const_iterator iter = str.begin();
    std::string::const_iterator end = str.end();
    bool r = phrase_parse(iter, end, g, space, emp);

    if (r && iter == end)
    {
        std::cout << "Parsing succeeded\n";
    }
    else
    {
        std::cout << "Parsing failed\n";
    }
    
    return 0;
}

Change History (3)

comment:1 by anonymous, 8 years ago

Up ?

comment:2 by Nikita Kniazev <nok.raven@…>, 5 years ago

The code compiles with the recent boost.

comment:3 by Joel de Guzman, 5 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.