Parsing command input with simple bimaps I've been playing with a simple toyrobot exercise to brush up some of my forgotten language skills and was wondering if there was a nicer way to implement my main command parsing loop.  I think the use of the two maps and the nested ternary operator is readable but would be interested in seeing other approaches.

#include "toyrobot.hpp"
#include &lt;iostream&gt;
#include &lt;regex&gt;
#include &lt;string&gt;
#include &lt;map&gt;

int main () {
  using namespace std;

  map&lt;string,int&gt; dirtoi = {{"NORTH", 0}, {"EAST", 1}, {"SOUTH", 2}, {"WEST", 3}};
  map&lt;int,string&gt; itodir = {{0, "NORTH"}, {1, "EAST"}, {2, "SOUTH"}, {3, "WEST"}};
  regex place("^PLACE (\\d),(\\d),(NORTH|EAST|SOUTH|WEST)$");

  Robot robot = Robot();
  Option&lt;Table&gt; table = Some(Table(Point(0,0),Point(4,4)));

  smatch m;
  string l;
  while (getline(cin, l))
  {
        l == "MOVE" ? robot.move() :
        l == "LEFT" ? robot.left() :
        l == "RIGHT" ? robot.right() :
        l == "REPORT" ? robot.report(itodir) :
        regex_match (l,m,place) ? robot.place(Point(stoi(m[1]), stoi(m[2]))
                                            , dirtoi.at(m[3])/2.0, table) :
    (void)0;
  }
}
Here are some things I saw and some suggestions for how you might improve your code.

Try not to repeat information

I don't much care for the two parallel maps because they have the same information but in two different places and in two different constructs.  What you actually seem to need is a way to go from a std::string to an int and vice-versa.  For that, I'd write a simple class that does this:

template &lt;class T&gt;
class Bimap
{
public:
    Bimap(std::initializer_list&lt;T&gt; init) : names{init} {}
    const T&amp; operator[](int i) const { return names[i]; }
    int operator[](const T&amp; n) const { 
        for (unsigned i=0; i &lt; names.size(); ++i) { 
            if (names[i] == n)
                return i;
        }
        return -1;
    }
private:
    std::vector&lt;T&gt; names;
};


Note that is, in fact, a templated class so it could be used with std::string or std::wstring or any other class that implements operator== and can be placed in a std::vector.  The simple linear search is not as efficient as a std::map but it's probably just fine for short lists.  Using it in main is just this line:

const Bimap&lt;string&gt; dir{{"NORTH", "EAST", "SOUTH", "WEST"}};


Use const where practical

Your regex and std::map variables could and should be const.  

Separate parsing from actions

The code is actually attempting to do two different things:  it is parsing a line from input and then calling some action based on what it finds.  It's probably useful to separate those two a little more clearly.  I'd probably use flex and bison if the commands become more complex, but for now you can simply use a more complete regex.  Here's one way to do that:

const Bimap&lt;string&gt; simplecmd{{"MOVE", "LEFT", "RIGHT", "REPORT"}};
enum scmd { MOVE, LEFT, RIGHT, REPORT };
const regex command("^(MOVE|LEFT|RIGHT|REPORT)|PLACE (\\d),(\\d),(NORTH|EAST|SOUTH|WEST)$");


By reusing the Bimap class defined above, we can change any command into an integer.  By expressing all possible commands within a regex, we can simply ignore any line which doesn't match (or perhaps print an error message).  

I'm not happy about having the parallel constructs of simplecmd and the enum scmd but couldn't think of an easy way to avoid it in this case.  We can rationalize it by saying that if one wished to have, say, both French and English versions, only the simplecmd would need to changed and not the enum.

Use better variable names

Generally, single letter variable names other than i and j for loop variables, are best avoided in favor of longer names.  The variable m is not too terrible, but the variable l is definitely a poor choice, not least because it's easily mistaken for the digit 1 or the letter i.  I changed it to line in the rewrite I did.

Use a switch statement where appropriate

Because your parser is selecting some action based on the input, we can make that much more explicit (and easier to read and maintain) by using a switch statement instead of the chained ternary operator.  Here's one way to do it, incorporating all of the other suggestions:

smatch m;
string line;
while (getline(cin, line))
{
    if (regex_match(line, m, command)) {
        switch(simplecmd[m[1]]) {
            case MOVE:
                robot.move();
                break;
            case LEFT:
                robot.left();
                break;
            case RIGHT:
                robot.right();
                break;
            case REPORT:
                robot.report();
                break;
            default:   // must be PLACE
                robot.place(Point(std::stoi(m[2]), std::stoi(m[3])), dir[m[4]], table);
        }
    }
}