help with boost::spirit:parsing out a list of menuitems
Hello: I have a client I'm writing, where the server sends data to the client to display as a menu in one instance. I wanted to use boost::spirit to parse this out. So, here's the code. I have three questions: 1) What can I do better/differently? 2) When I parse out my menuitem, if there's no flag, can it be set to 0 by default somehow? 3) Where is menuitem returned? Is there a way I can push it to a queue since I'll have more? My actual parser will look something like: pstart >> item >> *(delem >> item) >> pend; Here is the code I have currently: struct menuitem { std::string name; int flag; int choice; }; BOOST_FUSION_ADAPT_STRUCT( menuitem, (std::string, name) (int, flag) (int, choice)) namespace ascii = boost::spirit::ascii; namespace qi = boost::spirit::qi; //I'd like to just take a char* here, since that's my payload. copying the char* to a std::string will take extra time, is there a way to do that? BOOL Menu::Parse(const std::string &data, int length) { std::string::const_iterator it, itEnd; it = data.begin(); itEnd = data.end(); //we construct a few parsers to make things easier. qi::rule<std::string::const_iterator, char, ascii::space_type> pstart = qi::char_('['); qi::rule<std::string::const_iterator, char, ascii::space_type> pend = qi::char_(']'); qi::rule<std::string::const_iterator, char, ascii::space_type>delem = qi::char_('|'); qi::rule<std::string::const_iterator, menuitem(), ascii::space_type>item = qi::char_("a-zA-Z0-9 -.?!$@") >> qi::char_('(')
-qi::int_ >> qi::char_(':') >> qi::int_ >> qi::char_(')');
if (!qi::phrase_parse(it, itEnd, pstart >> item >> pend, ascii::space)) { return false; } return true; } -- Take care, Ty Web: http://tds-solutions.net The Aspen project: a light-weight barebones mud engine http://code.google.com/p/aspenmud Sent from my toaster.
2011/10/13 Littlefield, Tyler <tyler@tysdomain.com>
Hello: I have a client I'm writing, where the server sends data to the client to display as a menu in one instance. I wanted to use boost::spirit to parse this out. So, here's the code. I have three questions: 1) What can I do better/differently? 2) When I parse out my menuitem, if there's no flag, can it be set to 0 by default somehow?
See: http://boost-spirit.com/home/articles/doc-addendum/faq/#default
3) Where is menuitem returned?
The synthesized attribute you pass in (if any).
Is there a way I can push it to a queue since I'll have more?
By either auto attribute propagation or semantic action. I suggest the former if possible. My actual parser will look something like:
pstart >> item >> *(delem >> item) >> pend;
FYI, "item >> *(delem >> item)" can be replaced with "item % delem". Here is the code I have currently:
struct menuitem { std::string name; int flag; int choice; };
BOOST_FUSION_ADAPT_STRUCT( menuitem, (std::string, name) (int, flag) (int, choice))
namespace ascii = boost::spirit::ascii; namespace qi = boost::spirit::qi;
//I'd like to just take a char* here, since that's my payload. copying the char* to a std::string will take extra time, is there a way to do that?
const std::string &data -> char const* data std::string::const_**iterator -> char const* data.begin() -> data data.end() -> data + length ...and so on BOOL Menu::Parse(const std::string &data, int length)
{ std::string::const_iterator it, itEnd; it = data.begin(); itEnd = data.end();
//we construct a few parsers to make things easier.
qi::rule<std::string::const_**iterator, char, ascii::space_type> pstart = qi::char_('['); qi::rule<std::string::const_**iterator, char, ascii::space_type> pend = qi::char_(']'); qi::rule<std::string::const_**iterator, char, ascii::space_type>delem = qi::char_('|'); qi::rule<std::string::const_**iterator, menuitem(), ascii::space_type>item = qi::char_("a-zA-Z0-9 -.?!$@") >> qi::char_('(') >> -qi::int_ >> qi::char_(':') >> qi::int_ >> qi::char_(')');
if (!qi::phrase_parse(it, itEnd, pstart >> item >> pend, ascii::space)) { return false; } return true; }
Hello: Thanks for the info. I've put in a couple questions below: On 10/13/2011 2:42 AM, TONGARI wrote:
2011/10/13 Littlefield, Tyler <tyler@tysdomain.com <mailto:tyler@tysdomain.com>>
Hello: I have a client I'm writing, where the server sends data to the client to display as a menu in one instance. I wanted to use boost::spirit to parse this out. So, here's the code. I have three questions: 1) What can I do better/differently? 2) When I parse out my menuitem, if there's no flag, can it be set to 0 by default somehow?
See: http://boost-spirit.com/home/articles/doc-addendum/faq/#default awesome, thanks.
3) Where is menuitem returned?
The synthesized attribute you pass in (if any).
I'm confused here. Would someone mind explaining? I pass in menuitem() to one of the templates, but I'm not sure what that returns.
Is there a way I can push it to a queue since I'll have more?
By either auto attribute propagation or semantic action. I suggest the former if possible.
I'm not sure how to use the first. The second seems sort of easy, I would just use a function to do that, no? so: pstart >> item[boost::bind(&Parser::PushMenuItem, this, _1)] >> *(delem
item[boost::bind(&Parser::PushMenuItem, this, _1)] >> pend; ?
My actual parser will look something like: pstart >> item >> *(delem >> item) >> pend;
FYI, "item >> *(delem >> item)" can be replaced with "item % delem".
so the former would just be: pstart >> item[...]%delem >> pend; ?
Here is the code I have currently: struct menuitem { std::string name; int flag; int choice; };
BOOST_FUSION_ADAPT_STRUCT( menuitem, (std::string, name) (int, flag) (int, choice))
namespace ascii = boost::spirit::ascii; namespace qi = boost::spirit::qi;
//I'd like to just take a char* here, since that's my payload. copying the char* to a std::string will take extra time, is there a way to do that?
const std::string &data -> char const* data std::string::const_ iterator -> char const* data.begin() -> data data.end() -> data + length
...and so on
awesome, thanks. I didn't know that I could use that rather than an iterator
BOOL Menu::Parse(const std::string &data, int length) { std::string::const_iterator it, itEnd; it = data.begin(); itEnd = data.end();
//we construct a few parsers to make things easier.
qi::rule<std::string::const_ iterator, char, ascii::space_type> pstart = qi::char_('['); qi::rule<std::string::const_ iterator, char, ascii::space_type> pend = qi::char_(']'); qi::rule<std::string::const_ iterator, char, ascii::space_type>delem = qi::char_('|'); qi::rule<std::string::const_ iterator, menuitem(), ascii::space_type>item = qi::char_("a-zA-Z0-9 -.?!$@") >> qi::char_('(') >> -qi::int_ >> qi::char_(':') >> qi::int_ >> qi::char_(')');
if (!qi::phrase_parse(it, itEnd, pstart >> item >> pend, ascii::space)) { return false; } return true; }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Take care, Ty Web: http://tds-solutions.net The Aspen project: a light-weight barebones mud engine http://code.google.com/p/aspenmud Sent from my toaster.
Please, use plain text for better readability.
By either auto attribute propagation or semantic action. I suggest the former if possible.
I'm not sure how to use the first. The second seems sort of easy, I would just use a function to do that, no?
The former is even more simple: just pass std::vector as an attribute. The attribute of (a % b) is vector<A> http://www.boost.org/doc/libs/1_47_0/libs/spirit/doc/html/spirit/qi/quick_re...
const std::string &data -> char const* data std::string::const_ iterator -> char const* data.begin() -> data data.end() -> data + length ...and so on
awesome, thanks. I didn't know that I could use that rather than an iterator
char * is also iterator (random access iterator).
participants (3)
-
Igor R
-
Littlefield, Tyler
-
TONGARI