-
Notifications
You must be signed in to change notification settings - Fork 10
Functional Approaches
camio edited this page May 14, 2015
·
1 revision
See: https://github.com/wildcomputations/liaw2015/blob/master/lib/examples/readFromJsonAndCmdLine.txt Code:
struct Motor {
std::string name;
double maxVel;
};
struct Config {
std::net::ip_address server;
unsigned port;
std::vector<Motor> motors;
};
struct ConfigEditor {
boost::optional< std::net::ip_address > server;
boost::optional< unsigned > port;
std::vector<Motor> motors;
Config operator()( Config c ) {
if( server )
c.server = *server;
if( port )
c.port = *port;
std::copy( motors.begin(), motors.end(), std::back_inserter( c.motors ));
return c;
}
};
// Parser<A, B>: something that parses an object of type A into an object of type B.
//
// Parsers
// -------
// stringP : Parser< string, string >
// unsignedP : Parser< string, unsigned >
// ipAddressP : Parser< string, std::net::ip_address >
//
// Parsers Combinators
// -------------------
// >> : Parser< string, A > → Parser< string, B > → Parser< List< string >, pair< A, B > >
// >> : string → Parser< string, B > → Parser< List< string >, B >
// opt : Parser< List< string >, A > → Parser< List< string >, optional< A > >
// mix : Parser< List< string >, A₀ > > →
// … →
// Parser< List< string >, List< Aᵢ > > →
// Parser< List< string >, Tuple< A₀, …, Aᵢ > >
// *a : Parser< List< string >, A > → Parser< List< string >, vector< A > >
//
// Json Parsers/Combinators
// ------------------------
// Implicit conversion of Parser< string, A > to Parser< JsonValue, A >
//
// jsonObjectP :
// string -> Parser<JsonValue, A₀ > ->
// …
// string -> Parser<JsonValue, Aᵢ > ->
// Parser<JsonValue, Tuple< A₀, …, Aᵢ >
//
// jsonListP: Parser<JsonValue, A> → Parser<JsonValue, vector<A >>
auto motorGrammar = "--motor" >> stringP >> doubleP;
auto configEditorGrammar = mix(
opt( "--server" >> ipAddressP ),
opt( "--port" >> unsignedP ),
*motorGrammar );
auto jsonConfigEditorGrammar = jsonObjectP(
"server", ipAddressP,
"port", unsignedP,
"motors", jsonListP( jsonObjectP(
"name", stringP,
"maxVel", doubleP ) ),
);
int main( int argc, char ** argv ) {
Config defaultConfig{ "localhost", 8080, {} };
ConfigEditor cmdLineEditor = parseCommandLine( argc, argv, configEditorGrammar );
ConfigEditor jsonEditor = parseJsonFile( "config.json", jsonConfigEditorGrammar );
Config config = cmdLineEditor( jsonEditor( defaultConfig ) );
// ...
};