Question: Populate nested structs with semantic actions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Question: Populate nested structs with semantic actions

Emiliano Canedo
Hello,

I'm working in a parser with spirit qi. The grammar is working good, but I have some problems to populate my struct instance with Semantic Actions. With the direct struct attributes, like "Request.id" and "Request.url", the code is working. But I don't know how to populate the attributes inside the nested struct "Info", neither how to push values in "Request.list". Here is my code (The string to parse could have the values in any order):

//-----------------------------------------------------------------------------------------
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>

#include <iostream>
#include <vector>
#include <string>

struct Request
{
    std::string id;
    std::string url;
    std::vector<std::string> list;

    struct Info
    {
        std::string id;
        std::string desc;
    };
    Info info;
};

BOOST_FUSION_ADAPT_STRUCT(
    Request,
    (std::string, id)
)

template <typename Iterator>
struct request_parser : boost::spirit::qi::grammar<Iterator, Request(), boost::spirit::ascii::space_type>
{      
        request_parser() : request_parser::base_type(start)
        {
            using namespace boost::spirit::qi;
            namespace ascii = boost::spirit::ascii;
            namespace phx = boost::phoenix;
                                
            quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];

            start %=
                BR_OP
                >>((DQUOTE >> lit(INFO) >> DQUOTE >> COLON
                    >> BR_OP
                    >> ((DQUOTE >> lit(DESC) >> DQUOTE >> COLON >> quoted_string)
                    ^ (DQUOTE >> lit(ID) >> DQUOTE >> COLON >> quoted_string)) % COMMA
                    >> BR_CL)
                ^(DQUOTE >> lit(ID) >> DQUOTE >> COLON >> quoted_string[phx::bind(&Request::id, _val) = _1])
                ^(DQUOTE >> lit(URL) >> DQUOTE >> COLON >> quoted_string[phx::bind(&Request::url, _val) = _1])
                ^(DQUOTE >> lit(LIST) >> DQUOTE >> COLON
                    >> SQ_OP
                    >> quoted_string % COMMA
                    >> SQ_CL)) % COMMA
                >>
                BR_CL
                ;
        }
       
        boost::spirit::qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> quoted_string;
        boost::spirit::qi::rule<Iterator, Request(), boost::spirit::ascii::space_type> start;
       
        char BR_OP = '{';
        char BR_CL = '}';
        char DQUOTE = '"';
        char COLON = ':';
        char SQ_OP = '[';
        char SQ_CL = ']';
        char COMMA = ',';
       
        const char* LIST = "list";
        const char* ID = "id";
        const char* URL = "url";
        const char* INFO = "info";
        const char* DESC = "desc";
};

int main()
{
    typedef std::string::iterator iterator_type;
    typedef request_parser<iterator_type> requester_parser;
   
    std::string str = "{\"list\":[\"data1\",\"data2\"],\"info\":{\"desc\":\"description\",\"id\":\"23\"},\"id\":\"1234\",\"url\":\"ok.com\"}";
   
    Request rqst;
    requester_parser parser;
   
    using boost::spirit::ascii::space;
    boost::spirit::qi::phrase_parse(str.begin(), str.end(), parser, space, rqst);
   
    using std::cout;
    using std::endl;
    cout << rqst.id << endl;
    cout << rqst.url << endl;
    cout << rqst.list.size() << endl;
    cout << rqst.info.id << endl;
    cout << rqst.info.desc << endl;
}
//-----------------------------------------------------------------------------------------

Thanks!
Emiliano

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Question: Populate nested structs with semantic actions

sehe
On 16-03-17 21:51, Emiliano Canedo wrote:
> Hello,
>
> I'm working in a parser with spirit qi. The grammar is working good,
> but I have some problems to populate my struct instance with Semantic
> Actions. With the direct struct attributes, like "Request.id" and
> "Request.url", the code is working. But I don't know how to populate
> the attributes inside the nested struct "Info", neither how to push
> values in "Request.list". Here is my code (The string to parse could
> have the values in any order):

I've chosen to answer your question on stackoverflow:
https://stackoverflow.com/questions/42858759/populate-nested-structs-with-semantic-actions

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general