The boost spirit library allows for direct translation of a BNF grammar into C++ code which generates a parser at compile time. The following example, from http://spirit.sourceforge.net/distrib/spirit_1_8_3/libs/spirit/doc/introduction.html truly does this concept more justice than I could: BNF Example:

group      ::= '(' expression ')'
factor     ::= integer | group
term       ::= factor (('*' factor) | ('/' factor))*
expression ::= term (('+' term) | ('-' term))*

Translation to boost::spirit:

group      = '(' >> expression >> ')';
factor     = integer | group;
term       = factor >> *(('*' >> factor) | ('/' >> factor));
expression = term >> *(('+' >> term) | ('-' >> term));

A very simple (and complete) example that I have written shows you how to parse a simple dotted name value pair.

#include <boost/spirit.hpp>
#include <boost/spirit/actor/clear_actor.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>

using namespace std;
using namespace boost::spirit;

void myaction(vector &v, int &lastlen, 
  const char *begin, const char * end)
{
  string str(begin,end);
  if (!str.empty()) {
    v.clear();
    v.push_back(str);
    lastlen = 0;
  } else {
    v.resize(lastlen);
  }
}

bool parse_entries(char const* str, 
  vector& v, string &value)
{
  static int lastlen = 0;
  if (lastlen == 0) {
    lastlen = v.size();
  }
  return parse(str,

  //  Begin grammar
  (
    (!(+alpha_p))[boost::bind(&myaction, boost::ref(v), boost::ref(lastlen), _1, _2)] 
      >> *('.' >> (+alpha_p)[push_back_a(v)]) 
      >> !('=' >> (+(~ch_p('\n')))[assign_a(value)])
  )
  ,
  //  End grammar
  space_p).full;
}

int main()
{
  vector input;
  input.push_back("black.abba.baab.bob");
  input.push_back(".cat = 52 woot woot");
  input.push_back(".dog= 23");
  input.push_back("chicken = 42");

  vector v;

  for (vector::const_iterator itr2 
         = input.begin();
       itr2!=input.end();
       itr2++) 
  {
    string value;
    parse_entries(itr2->c_str(), v, value);

    for (vector::const_iterator itr 
           = v.begin();
         itr != v.end();
         itr++)
    {
      cout << *itr << endl;
    }

    cout << value << endl << endl;
  }
}

In this example if the input begins with a ‘.’ the context for the key name is maintained from the last entry. Go ahead and give it a go.