Jump to content
  • Advertisement
Sign in to follow this  
Telastyn

Parsers for the common man?

This topic is 4834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

During my [yet another rewrite of the same] project (in c++), I kinda wandered into writing some structures and code to generically take string input [such as from the console of a server, or a quake style console], parse/lookup/convert it, and pass it along to internal functions. After I got it working, I figured I should probably look around for pre-made libraries which do the same thing. Backwards I know, but I did not intend for the code to stray into such constructs. And please note, I'm terrible at reading through library docs due to my informal learning. Please correct anything I've missed or misinterpreted. Anyways, I looked at boost first, as boost tends to deal with such black magic, and I know of boost::format which seems similar to the syntax definitions needed for this sort of thing. It though does not seem to work in reverse [taking from an istream, rather than formatting for an ostream]. Google led me to pages regarding lex, yacc, bison and their kin. These seem to do the same sort of thing, I think. They do look to be complete overkill if so. So for those who don't do nifty binding with lua and python [which I imagine will do the same thing], how is this sort of thing normally done? In the past, I just explicitly made a largeish if/elsif block and manually converted each token as it came. Functional, but a pita. The new code should be better, but I've not used it enough to get a feel for its difficiencies.

Share this post


Link to post
Share on other sites
Advertisement
You looked at boost, but didn't find Boost Spirit?

It's perfect for this kind of thing if you ask me.

Very simple example which utilizies near zero features of the library:

#include <boost/spirit.hpp>

int main( int argc , char ** argv )
{
std::string input = "{30.0,-14.3,18.2}";
double x,y,z;

using namespace boost::spirit;

parse( input.begin() , input.end() ,
ch_p('{')
>> real_p[ assign_a( x ) ]
>> ','
>> real_p[ assign_a( y ) ]
>> ","
>> real_p[ assign_a( z ) ]
>> str_p("}")
);

assert( (x - 30.0) < 0.01 );
assert( (y - -14.3) < 0.01 );
assert( (z - 18.2) < 0.01 );
}





Read up on the documentation for more complex examples.

Sidenote: ch_p and str_p arn't actually necessary in this example. I'd probably keep the first ch_p, simply because you then don't have errors compiling if you have two seperate strings/characters to start your "grammar".

Share this post


Link to post
Share on other sites
Ah, you'll excuse me if I didn't think what I was looking for would be under such a peculiar name.

Though this too seems [like most of boost seems] to be complete overkill. Though I suspect this BNF stuff is much like regular expressions, seems like complete overkill until you learn it and realise that only maybe 10% of the stuff is really needed for most things.

Well, something to look at tomarrow.

Share this post


Link to post
Share on other sites
You could try a map with a string + function object (function pointer) as the key-value pair. I'm not sure how efficient it is, but it beats the heck out of writing humongous switch statements. It's also part of the STL so you should be able to find documentation on maps and what-not.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!