Skip to content

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 ) );

  // ...
};
Clone this wiki locally