Skip to content

Instantly share code, notes, and snippets.

@mrexodia
Created March 21, 2015 23:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrexodia/556f10434036f5a97679 to your computer and use it in GitHub Desktop.
Save mrexodia/556f10434036f5a97679 to your computer and use it in GitHub Desktop.
Command Parser
#include "command.h"
Command::Command(const String & command)
{
ParseState state = Default;
int len = command.length();
for(int i=0; i<len; i++)
{
char ch = command[i];
switch(state)
{
case Default:
switch (ch)
{
case ' ':
if (!_tokens.size())
dataFinish();
break;
case ',':
dataFinish();
break;
case '\\':
state = Escaped;
break;
case '\"':
state = Text;
break;
default:
dataAppend(ch);
break;
}
break;
case Escaped:
dataAppend(ch);
state = Default;
break;
case Text:
switch (ch)
{
case '\\':
state = TextEscaped;
break;
case '\"':
dataFinish();
state = Default;
break;
default:
dataAppend(ch);
break;
}
break;
case TextEscaped:
dataAppend(ch);
state = Text;
break;
}
}
dataFinish();
}
const String Command::GetText()
{
return _tokens.size() ? _tokens[0] : String();
}
const int Command::GetArgCount()
{
return _tokens.size() ? _tokens.size() - 1 : 0;
}
const String Command::GetArg(int argnum)
{
return (int)_tokens.size() < argnum + 1 ? String() : _tokens[argnum+1];
}
void Command::dataAppend(const char ch)
{
_data += ch;
}
void Command::dataFinish()
{
if(_data.length())
{
_tokens.push_back(_data);
_data = "";
}
}
#ifndef _COMMAND_H
#define _COMMAND_H
#include <string>
#include <vector>
typedef std::string String;
class Command
{
public:
Command(const String & command);
const String GetText();
const String GetArg(const int argnum);
const int GetArgCount();
private:
String _data;
std::vector<String> _tokens;
enum ParseState
{
Default,
Escaped,
Text,
TextEscaped
};
void dataFinish();
void dataAppend(const char ch);
};
#endif // _COMMAND_H
#include <iostream>
#include "command.h"
using namespace std;
int main()
{
string cmd;
cout << ">";
getline(cin, cmd);
Command command(cmd);
cout << "GetText: " << command.GetText() << endl;
int argc=command.GetArgCount();
if(argc)
{
cout << "GetArgCount: " << argc << endl;
cout << "Args:" << endl;
for(int i=0; i<argc; i++)
{
cout << i << ": " << command.GetArg(i) << endl;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment