Re: multi containers and arbitrary insertion.

Mikael Asplund <[email protected]> Wed, 28 Mar 2018 08:03:58 +0000
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
From your example, and your structs and your parser rules, I can't figure out what you're trying to achieve. Could you describe it with pure English?
Are you trying to parse a list of "vect"s and "map"s, in mixed order, and get a struct with a two lists, one with all the "vects" and one with all the "map"?

  /Mikael

-----Original Message-----
From: Dan Bloomquist <[email protected]> 
Sent: Wednesday, March 28, 2018 04:34
To: Spirit General Mailing List <[email protected]>
Subject: [Spirit-general] multi containers and arbitrary insertion.


I've really tried to get this to work. I have learned a lot but I'm still stuck. I have comments in the code below, see: 'This is what I would really like to parse'. I'm so close!
Thanks, Dan.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <boost/spirit/home/x3.hpp>
//must fuse std::pair for maps
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

#include <iostream>
#include <unordered_map>

namespace ast {
     namespace x3 = boost::spirit::x3;
     //struct nil{};
     //struct Dual;
     //struct Dual2;
     //struct Holder;

     //typedef x3::variant <
     //    nil,
     //    x3::forward_ast<Dual>,
     //    x3::forward_ast<Dual2>
     //> Type;

     // .........................................................
     struct Dual
     {
         std::string name;
         int num;
         int another; // not used....
         bool operator < (const Dual& d) { return d.name < name; }
     };
     using DualMap = std::unordered_map<std::string, Dual>;

         // .........................................................
     struct Dual2
     {
         std::string name;
         int num;
     };
     using Dual2Vect = std::vector<Dual2>;

         // .........................................................
     struct Holder
     {
         std::string dummy;
         std::unordered_map<std::string, Dual> themap;
         std::vector<Dual2> thevect;
     };

}// namespace ast

BOOST_FUSION_ADAPT_STRUCT(ast::Dual,
     name,
     num
)
BOOST_FUSION_ADAPT_STRUCT(ast::Dual2,
     name,
     num
)
BOOST_FUSION_ADAPT_STRUCT(ast::Holder,
     dummy,
     thevect,
     themap
)

// .........................................................
// parser namespace.........................................
using namespace boost::spirit::x3;
using namespace ast;

#define DEF_RULE( RuleName, Attr ) static auto const RuleName = rule<struct Attr##_def, Attr>( #RuleName )

auto const bare_word
     = lexeme[+char_("a-zA-Z0-9_")];

auto const quoted_string
     = lit('"') >> bare_word >> lit('"');

DEF_RULE(dual_rule, Dual) = bare_word >> int_; DEF_RULE(dual2_rule, Dual2) = lit("vect") >> bare_word >> int_;

static auto const dual_map_rule = lit("map") >> quoted_string >> dual_rule;

//this works but not what I'm after
static auto const all_rule = x3::skip(x3::space)[ bare_word >> 
+dual2_rule >> +dual_map_rule];

//would like this, but can't get it to be the right size for the 'Holder' class static auto const all_rule2 = x3::skip(x3::space)[bare_word >> 
+dual2_rule | +dual_map_rule];

DEF_RULE(holder_rule, Holder) = bare_word >> all_rule;

BOOST_SPIRIT_DEFINE(dual_rule, dual2_rule, holder_rule)

// .........................................................
// .........................................................
//This is what I would really like to parse.
const static std::string thestr( R"(
hold_name
vect name1 123
map "test1" namea 234
map "test2" nameb 345
vect name2 456
)" );
//And in that case I really don't want to use the plus type Kleene, but 
containers expect it!??

int main()
{
     std::cout << "fusion::size: " <<
boost::fusion::result_of::size<traits::attribute_of<decltype(quoted_string 
 >> dual_rule >> -lit(',')), unused_type>::type>::value << std::endl;

//test
     {
         std::string str("map \"mark1\" name 123\n map \"mark2\" and 234");
         auto begin = str.begin();
         auto end = str.end();

         std::unordered_map< std::string, Dual > map;
         auto r = phrase_parse(begin, end, +dual_map_rule, space, map);
         std::cout << std::boolalpha << "pass: " << r << " at: " << 
std::string(begin, end) << std::endl;
     }
     {
         std::string str("vect name1 1 vect name2 2\n\r vect name3 3");
         auto begin = str.begin();
         auto end = str.end();

         std::vector< Dual2 > vect;
         auto r = phrase_parse(begin, end, +dual2_rule, space, vect);
         std::cout << std::boolalpha << "pass: " << r << " at: " << 
std::string(begin, end) << std::endl;
         size_t x = 0;

     }
     {
         std::string str("hold_name  vect stuff1 21  vect stuff2 22\n 
vect stuff3 33 map \"mark1\" name 123\n vect more 42");
// ^
//stops here with success
         //str = thestr;
         std::string::iterator begin = str.begin();
         std::string::iterator end = str.end();

         Holder hdual;
         bool r = phrase_parse(begin, end, all_rule, space, hdual);

         std::cout << std::boolalpha << "pass: " << r << " at: " << 
std::string(begin, end) << std::endl;
         //and...
         for (auto& item : hdual.thevect)
             std::cout << item.name << ", " << item.num << std::endl;
     }
     return 0;
}


------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot