First write down the syntax of what you support, then write the code to support it.
Using BNF notation is great for that. And using the Spirit library for the code-part is quite straightforward.
Command := ACommand | BCommand
ACommand := 'A' AOperation
AOperation := 'some_operation' | 'some_other_operation'
BCommand := 'B' BOperation
BOperation := 'some_operation_for_B' | 'some_other_operation_for_B'
This easily translates into a Spirit parser. Every production rule would become a one-liner, every end-symbol would be translated into a function.
#include "stdafx.h"
#include <boost/spirit/core.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost::spirit;
namespace {
void AOperation(char const*, char const*) { cout << "AOperation\n"; }
void AOtherOperation(char const*, char const*) { cout << "AOtherOperation\n"; }
void BOperation(char const*, char const*) { cout << "BOperation\n"; }
void BOtherOperation(char const*, char const*) { cout << "BOtherOperation\n"; }
}
struct arguments : public grammar<arguments>
{
template <typename ScannerT>
struct definition
{
definition(arguments const& /*self*/)
{
command
= acommand | bcommand;
acommand = chlit<char>('A')
>> ( a_someoperation | a_someotheroperation );
a_someoperation = str_p( "some_operation" ) [ &AOperation ];
a_someotheroperation = str_p( "some_other_operation" )[ &AOtherOperation ];
bcommand = chlit<char>('B')
>> ( b_someoperation | b_someotheroperation );
b_someoperation = str_p( "some_operation_for_B" ) [ &BOperation ];
b_someotheroperation = str_p( "some_other_operation_for_B" )[ &BOtherOperation ];
}
rule<ScannerT> command;
rule<ScannerT> acommand, bcommand;
rule<ScannerT> a_someoperation, a_someotheroperation;
rule<ScannerT> b_someoperation, b_someotheroperation;
rule<ScannerT> const&
start() const { return command; }
};
};
template<typename parse_info >
bool test( parse_info pi ) {
if( pi.full ) {
cout << "success" << endl;
return true;
} else {
cout << "fail" << endl;
return false;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
arguments args;
test( parse( "A some_operation", args, space_p ) );
test( parse( "A some_other_operation", args, space_p ) );
test( parse( "B some_operation_for_B", args, space_p ) );
test( parse( "B some_other_operation_for_B", args, space_p ) );
test( parse( "A some_other_operation_for_B", args, space_p ) );
return 0;
}