1 Replies - 13555 Views - Last Post: 07 August 2006 - 04:41 AM Rate Topic: -----

#1 dorknexus   User is offline

  • or something bad...real bad.
  • member icon

Reputation: 1272
  • View blog
  • Posts: 4,625
  • Joined: 02-May 04

Command parser

Posted 06 August 2006 - 06:40 PM

I have completed porting my command parser so that it runs independently from it's original implementation by use of the standard library. I think there are still some bugs in the area of parameters and their corresponding values. I would be interested to see what you guys think about my solution, and if there are better techniques for command parsers. At this point, there is a lack of commenting, I will be adding more comments in my next version.

Command syntax looks like so:

#<command> @<target> -<param> <value>

Example:

Quote

#open @file.txt -editor notepad


I will post the code in code boxes, and will also attach the source in a zip archive.

main.cpp
/******************************
Name: Nexus Command Parser (NCP)
Author: Justin Kenworthy (Dark_Nexus) 
******************************/

#include <iostream>
#include "nexcommand.h"

int main( int argc, const char* argv[])
{
	int exit_val = 0;

	string input;

	cout << "Enter command> ";
	getline(cin,input);

	cout << "Analyzing input: \"" << input << "\"" << endl;

	NEX_Command cmd(input);

	cout << "Command = " << cmd.command << "(END)" << endl;
	cout << "Target  = " << cmd.target << "(END)" << endl;
	cout << "Param   = " << cmd.getParam("test") << "(END)" << endl;

	return exit_val;
}



nexcommand.h
#ifndef NEXCOMMAND_H
#define NEXCOMMAND_H

#include <string>
#include <list>

using namespace std;

class NEX_Command
{
private:

	/*****Parameter*****/
	struct param_t
	{
		string label;
		string value;
	};
	/*******************/
	
public:
	string command;
	string target;

	list <param_t> paramList;

	NEX_Command(string cmd);

	bool checkParam(const char *p);
	string getParam(const char *p);
	int checkCommand(const char *check);
	void passBuffer(string *dest,string::iterator *beg,string::iterator end,bool *flag);

	void parseCommand(string cmd);
};

#endif



nexcommand.cpp
#include "nexcommand.h"

/*****Constructors*****/

//nex_command(const char *cmd)
NEX_Command::NEX_Command(string cmd)
{
	parseCommand(cmd);
}

/*****Destructors*****/

//checkParam(...)
bool NEX_Command::checkParam(const char *p)
{
	list <param_t>::iterator pl_end = paramList.end();

	for (list <param_t>::iterator pl_iter = paramList.begin();pl_iter != pl_end;pl_iter++)
	{
		if (pl_iter->label.compare(p) == 0)
			return true;
	}

	return false;
}

//checkCommand(...)
int NEX_Command::checkCommand(const char *check)
{
	return (command.compare(check));
}

//getParam(...)
string NEX_Command::getParam(const char *p)
{
	list <param_t>::iterator pl_end = paramList.end();

	for (list <param_t>::iterator pl_iter = paramList.begin();pl_iter != pl_end;pl_iter++)
	{
		if (pl_iter->label.compare(p) == 0)
			return pl_iter->value;
	}

	return "";
}

//passBuffer(...)
void NEX_Command::passBuffer(string *dest,string::iterator *beg, string::iterator end, bool *flag)
{
	dest->assign(*beg,end);

	*beg = end;		//Move beg iterator to end iterator
	*flag = false;	//Set command flag to false
}

//parseCommand(...)

void NEX_Command::parseCommand(string str)
{
	int len = str.size();

	//Input buffers
	param_t param;

	string::iterator key = str.begin(); //Position index

	//Flags for disecting command
	bool inParam = false;
	bool inValue = false;
	bool inQuotes = false;
	bool inCommand = false;
	bool inTarget = false;

	for (int i = 0;i < len;++i)
	{
		switch (str[i])
		{
		case '\"':	//Quotes
			{
				if (inQuotes == true)
				{
					if (inCommand)
					{
						passBuffer(&command,&key,&str.at(i),&inCommand);			
					}
					else if (inTarget)
					{
						passBuffer(&target,&key,&str.at(i),&inTarget);
					}
					else if (inParam)
					{
						passBuffer(&param.label,&key,&str.at(i),&inParam);
						paramList.push_back(param);
					}
					else if (inValue)
					{
						passBuffer(&param.value,&key,&str.at(i),&inValue);
						paramList.push_back(param);
					}
				}

				inQuotes = !(inQuotes); //Flip-flop state
				key = &str.at(i + 1);
			}
			break;
		case '-':	//Parameter prefix
			{
				if ((inQuotes == false) &&
					(inCommand == false) &&
					(inTarget == false) &&
					(inValue == false) &&
					(inParam == false))
				{
					key = &str.at(i + 1);
					inParam = true;
				}
			}
			break;
		case '#':	//Command prefix
			{
				if ((inQuotes == false) &&
					(inCommand == false) &&
					(inTarget == false) &&
					(inValue == false) &&
					(inParam == false))
				{
					key = &str.at(i + 1);
					inCommand = true;
				}
			}
			break;
		case ' ':	//Space
			{				
				if (inQuotes == false)
				{
					if (inCommand)
					{
						passBuffer(&command,&key,&str.at(i),&inCommand);
					}
					else if (inTarget)
					{
						passBuffer(&target,&key,&str.at(i),&inTarget);
					}
					else if (inParam)
					{
						passBuffer(&param.label,&key,&str.at(i),&inParam);
						inValue = true;
					}
					else if (inValue)
					{
						passBuffer(&param.value,&key,&str.at(i),&inValue);
						paramList.push_back(param);
					}
					else
						key = &str.at(i + 1);
				}
			}
			break;
		case '@':	//Target prefix
			{
				if (inQuotes == false)
				{
					if (inCommand == true)
					{
						passBuffer(&command,&key,&str.at(i),&inCommand);
					}
					if ((command.empty() == false) &&
						(inTarget == false) &&
						(inValue == false) &&
						(inParam == false))
					{
						key = &str.at(i + 1);
						inTarget = true;
					}
				}
			}
			break;
		}
	}

	//Finalize command
	if (inCommand)
	{
		passBuffer(&command,&key,str.end(),&inCommand);
	}
	else if (inTarget)
	{
		passBuffer(&target,&key,str.end(),&inTarget);
	}
	else if (inParam)
	{
		passBuffer(&param.label,&key,str.end(),&inParam);
		paramList.push_back(param);
	}
	else if (inValue)
	{
		passBuffer(&param.value,&key,str.end(),&inValue);
		paramList.push_back(param);
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: Command parser

#2 Mrafcho001   User is offline

  • D.I.C Addict
  • member icon

Reputation: 41
  • View blog
  • Posts: 769
  • Joined: 01-November 05

Re: Command parser

Posted 07 August 2006 - 04:41 AM

without having a compiler and by simply looking at the code, i have to say it looks good. Should do a bit more error checking and handeling but other than that its good.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1