Parser.cc 4.41 KB
/**
 * Parser.cc
 *
 *  Created on: Dec 11, 2012
 *      Author: AKKA IS
 */
#include <ctype.h>
#include <sstream>

#include "DicError.hh"
#include "AMDA_exception.hh"

#include "Parser.hh"
#include "ParamData.hh"
#include <boost/functional/hash.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
namespace AMDA {
namespace Parameters {

Parser::Parser() : _expression(""), _paramOnly(false), _processOnly(false) {

}

Parser::~Parser() {

}

void Parser::process(std::string expression) {
	_expression=expression;
	string::iterator it = _expression.begin();
	_paramOnly = false;
	_processOnly = false;
	while(it != _expression.end()) {
		switch(*it) {
		case '$':
			_paramOnly = (it == _expression.begin());
			_processOnly = false;
			processParameterName(++it) ;
			break;
		case '#':
			_paramOnly = false;
			_processOnly = (it == _expression.begin());
			processProcessName(++it);
			break;
		default:
			_paramOnly = false;
			_processOnly = false;
			if(isalpha(*it)) {
				processFctName(it);
			}
			else {
				_formulaCC.append(1, *it);
				_constructorCC.append(1, *it);
				++it;
			}
			break;
		}
	}

}

std::string Parser::findAlphaNum_(std::string::iterator &it) {

	string pParamName = "";
	while(it != _expression.end() &&  (isalnum(*it) || *it == '_')) {
		pParamName.append(1, *it);
		++it;
	}
	return pParamName;
}

void Parser::processParameterName(std::string::iterator &it) {
	string pParamName = findAlphaNum_(it);
	_listParameterName.insert(pParamName);
	_formulaCC += pParamName + ParamData::getAccessor();
	_constructorCC += "(static_cast<_T_" + boost::to_upper_copy(pParamName) + "_Element_Type>(_T_" + boost::to_upper_copy(pParamName) + "_Element_Type()))";
}

void Parser::processProcessName(std::string::iterator &it) {
	string pProcessName = "";
	while(it != _expression.end() &&  (isalnum(*it) || *it == '_')) {
		pProcessName.append(1, *it);
		++it;
	}

	AttributList attribut;
	std::string expression = processProcessExpression(it, attribut);

	boost::hash<std::string> string_hash;

	std::stringstream buffer;
	buffer << expression;
	for (AttributList::iterator it = attribut.begin(); it != attribut.end(); ++it) {
		buffer << "_" << *it;
	}
	std::stringstream key;
	key << pProcessName << "_" << string_hash(buffer.str());
	_listProcessName[key.str()] = ProcessInfo(pProcessName, expression, attribut);
	_formulaCC += key.str() + ParamData::getAccessor();
	_constructorCC += "(static_cast<_T_" + boost::to_upper_copy(key.str()) + "_Element_Type>(_T_" + boost::to_upper_copy(key.str()) + "_Element_Type()))";

}

size_t Parser::searchSemiColon(const char* expression) {
	size_t result = string::npos;
	int nbBraket = 0;
	unsigned int length = strlen(expression);
	for ( unsigned int i = 0; i < length; ++i) {
		switch(expression[i]) {
		case '(': ++nbBraket; break;
		case ')': --nbBraket; break;
		case ';': if ( nbBraket == 0 ) { return i; } break;
		default:
			break;
		}
	}
 return result;
}


std::string  Parser::processProcessExpression(std::string::iterator &it, AttributList &attribut) {

	string lProcessExpression = "";
	while(*it==' ') ++it;

	if(*it == '(') {
		int nbBraket = 1;
		++it;
		while(it!=_expression.end() && nbBraket > 0) {
			if(*it == '(') ++nbBraket;
			if(*it == ')') --nbBraket;
			if(nbBraket > 0) lProcessExpression.append(1, *it);
			++it;
		}
	}
	else {
	    BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_PROCESS_ERR) << AMDA::ex_msg(std::string("Bad format")));
	}

	size_t indexOfFirstSemiColon  = 0;
	size_t indexOfSecondSemiColon = searchSemiColon(lProcessExpression.c_str()+indexOfFirstSemiColon);

	string lSubExpression = "";

	if (indexOfSecondSemiColon == string::npos) {
		lSubExpression=lProcessExpression;
	} else {
		lSubExpression=lProcessExpression.substr(indexOfFirstSemiColon, indexOfSecondSemiColon);
		indexOfFirstSemiColon+=indexOfSecondSemiColon+1;
		while((indexOfSecondSemiColon=searchSemiColon(lProcessExpression.c_str()+indexOfFirstSemiColon))!=string::npos) {
			attribut.push_back(lProcessExpression.substr(indexOfFirstSemiColon, indexOfSecondSemiColon));
			indexOfFirstSemiColon+=indexOfSecondSemiColon+1;
		}
		attribut.push_back(lProcessExpression.c_str()+indexOfFirstSemiColon);
	}

	return lSubExpression;
}

void Parser::processFctName(std::string::iterator& it) {
	string pFctName = findAlphaNum_(it);
	if(*it == '(') {
	_listFctName.insert(pFctName);
	}
	_formulaCC += pFctName;
	_constructorCC += pFctName;
}

} /* namespace Parameters */
} /* namespace AMDA */