Jump to content
  • Advertisement
Sign in to follow this  
codemonkey423

Simple command parser?

This topic is 3538 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How would I implement a simple command parser? I was planning on starting out simple by just implementing commands and then later adding things like parameters. How would I do this? Would I have a list of commands that execute when the parser matches the command to something user types? Does that mean I'd have to treat parameters as separate commands?

Share this post


Link to post
Share on other sites
Advertisement
Well, if you were using Python, you could just take strings from the user with something like raw_input() and dumping them in eval(). If not using Python, then please specify what language you are using, and possibly other pertinent information like how you want user input to occur with your application.

Share this post


Link to post
Share on other sites
Sorry, I always forget to mention which language I'm using. I'm going to be using C++. For the time being the user will be using a console window, like a DOS prompt.

Share this post


Link to post
Share on other sites
Boost Spirit, or older, battle-tested Lex/Yacc and descendants (Flex/Bison, etc.).

Another option more aimed at actually solving the task rather than exploring techniques is exposing your functions via Lua, possibly by using a choice of wrapper/interface libraries.

There's also Boost program options, which is specifically aimed at GNU-like command-line parsing.

For trivial parsing, simple string tokenization might work as well.

Share this post


Link to post
Share on other sites
It really depends on how simple of commands you're want to use. I have one application with a main loop that looks like:

for (;;) {
std::cout << ">>> " << std::flush;
std::string command_line;
getline(std::cin, command_line);

std::stringstream sstr(command_line);
std::string command;
sstr >> command;

if (command == "scan") {
std::string name;
int value;
sstr >> name >> value;
// do stuff for scan
} else if (command == "filter") {
std::string name;
int value;
sstr >> name >> value;
// do stuff for filter
} else if (command == "display") {
std::string name;
sstr >> name;
// do stuff for display
} // and more commands

Hardly award winning code, but it works fine for the very simple commands the program was supposed to work with.

Share this post


Link to post
Share on other sites
If I may, what exactly is all of this?

std::cout << ">>> " << std::flush;
std::string command_line;
getline(std::cin, command_line);

std::stringstream sstr(command_line);
std::string command;
sstr >> command;


Pardon the very novice question, but why not just use cin >> command? (I'm sure there's a good reason, I'm just curious.)

Share this post


Link to post
Share on other sites
He/you could, but then you're constraining your quake-style console to only process stuff from standard in. You often don't want that (input via GUI, input via config file, via network...)

Share this post


Link to post
Share on other sites
cin>>stuff will only work for a single word, or up to the first space. His solution takes in the entire line, and then stores it for convenient access.

Share this post


Link to post
Share on other sites
Im not to sure if this is what you want, but in my systems parser I have a base class declared like this (A little modified to better suit C++ library) :

//! internal command
class internal_cmd {

public:

std::string m_name;
int m_flags;

virtual void desc () = 0;
virtual char* desc_short () = 0;
virtual int callback (char*) = 0;
};


You can store a list of all of the commands in an std::vector<> or std::list<> and create them dynamically (i.e., internal_cmd* cmd = new specific_cmd). Create a class for a new command and execute the command like this (Not tested) :
//! this is command to test
std::string inputbuf;

std::vector <internal_cmd*>::iterator it = cmds.begin();
for (; it != cmds.end(); it++)

if (*it)
if ((*it)->m_name == inputbuf) {

(*it)->callback (command_parms);
break;
}

This allows your command parser to treat each command as the same base class and execute the command by calling the commands callback method. This also provides a separation between your command parser and the actual commands themselves.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!