# Parsers for the common man?

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

## 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 on other sites
strtok and an hash table i guess.

##### Share on other sites
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 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 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 on other sites
If you really want to know everything required to make a compiler (of which parsing is a large part), I'd suggest the book Compilers: Principles, Techniques, and Tools.

• 36
• 15
• 9
• 23
• 10