コード例 #1
0
Datum ComponentRegistry::getNumber(std::string expression, GenericDataType type){

  Datum value;
    switch(type){
      case M_FLOAT:
      case M_INTEGER:
      case M_BOOLEAN:
      case M_STRING:
          value = getValue(expression, type);
          if (value.getDataType() == type) {
              return value;
          }
          break;
      default:
          throw FatalParserException("Attempt to cast a number of invalid type");
    }
	
	switch (type){
	
		case M_FLOAT:
			return Datum(value.getFloat());
		case M_INTEGER:
			return Datum(value.getInteger());
		case M_STRING:
			return Datum(value.getString());
		case M_BOOLEAN:
			return Datum(value.getBool());
		default:
			return value;			
	}
}
コード例 #2
0
Datum ComponentRegistry::getValue(std::string expression, GenericDataType type) {

  std::pair<std::string, GenericDataType> cacheKey(expression, type);
  shared_ptr<Datum> test = data_cache[cacheKey];
  if(test != NULL){
    return *test;
  }
  
  double doubleValue;
  long longValue;
  bool boolValue;
  Datum value;
  try {
    switch(type){
      case M_FLOAT:
      case M_INTEGER:
      case M_BOOLEAN:
            doubleValue = boost::lexical_cast<double>(expression);
            if (M_FLOAT == type) {
                value = Datum(doubleValue);
            } else if (M_INTEGER == type) {
                longValue = (long)doubleValue;
                if ((double)longValue != doubleValue) {
                    
                    throw NonFatalParserException("invalid integer literal", expression.c_str());
                }
                value = Datum(longValue);
            } else {
                boolValue = (bool)doubleValue;
                if ((double)boolValue != doubleValue) {
                    
                    throw NonFatalParserException("invalid boolean literal", expression.c_str());
                }
                value = Datum(boolValue);
            }
            break;
      case M_STRING:
          value = Datum(string(expression));
          break;
      default:
          // No lexical_cast for other types
          break;
    }
    
    if (!value.isUndefined()) {
        data_cache[cacheKey] = shared_ptr<Datum>(new Datum(value));
        return value;
    }
  } catch (NonFatalParserException& e){
      // Until we work out how to effectively flag these issues, treat them as fatal errors
      throw FatalParserException(e.what());
  } catch (boost::bad_lexical_cast& e){
    // no biggie, we can do this the hard(er) way
  }
  
  
	return Datum(ParsedExpressionVariable::evaluateExpression(expression));
}
コード例 #3
0
BEGIN_NAMESPACE_MW


FreezableVariableContainer::FreezableVariableContainer(shared_ptr<Variable> _var){
    frozen = false;
    variable = _var;
    if(variable == NULL){
        // TODO: make a better exception here; this is only effective for debugging as stands
        throw FatalParserException("Registering an empty variable within a FreezableVariableContainer "
                                   "(is there an empty variable passed into a Stimulus object?)");
    }
}
コード例 #4
0
shared_ptr<mw::StimulusNode>	ComponentRegistry::getStimulus(std::string expression){
	
	// regex for parsing the stimulus string
    boost::regex stimulus_regex("(.+?)(\\[(.+)\\])?");
	
    boost::smatch matches;
	try{
		
		regex_match(expression, matches, stimulus_regex); 
		// matches[0] contains the whole string 
		// matches[1] contains the stimulus "stem" 
		// matches[2] contains the index expression (if there is one), 
		//			  including brackets. 
		// matches[3] contains the index expression (if there is one), 
		//			  without brackets.
		
   } catch (boost::regex_error& e) {
		throw FatalParserException("Regex error during stimulus parsing (regex_error exception)", e.what());
   }
   
   // Something is wrong if there aren't at least two strings in matches
   if(matches.size() == 1){
		// TODO: throw
		throw FatalParserException("Regex error during stimulus parsing (not enough matches)");
	}
   
	// This the part before any brackets
	std::string stem = matches[1];
	
	std::string remainder = matches[2];
	if(remainder.empty()){
		return getStimulusNode(stem);
	}
	
	// If we're still going, from this point forward, the stem refers to a 
	// stimulus group
	shared_ptr<StimulusGroup> stimulus_group = getObject<StimulusGroup>(stem);
	
    if(stimulus_group == NULL){
        throw FatalParserException("Unknown stimulus group", stem);
    }
    
	shared_ptr<StimulusNodeGroup> stimulus_node_group = getObject<StimulusNodeGroup>(stem + ":node");
	
	if(stimulus_node_group == NULL){
		stimulus_node_group = shared_ptr<StimulusNodeGroup>(new StimulusNodeGroup(stimulus_group));
		
		shared_ptr<mw::Component> newStimulusNodeGroup = boost::dynamic_pointer_cast<mw::Component, StimulusNodeGroup>(stimulus_node_group);
		registerObject(stem + ":node", newStimulusNodeGroup);
	}
	
	if(stimulus_group == NULL){
		throw FatalParserException("Unknown stimulus group", stem);
	}
	
	// This is the stuff inside the outer brackets
	std::string index_pattern = matches[3];
	

	// This is where we are going to put the string when we are done with it
	std::string index_expression;
	
	// A regex to determine if the stimulus is multidimensional, e.g. stim[1][2]
	boost::regex multi_dimensional_group_regex(".+\\]\\s*\\[.+");
	if( regex_match(index_pattern, multi_dimensional_group_regex) ){
		
		// If it's multidimensional, we need to split up the contents of the
		// outer brackets and multiply/add them into a c-style multidimensional
		// array index. 

		// We're going to use this string stream for syntactic convenience in
		// concatenating things together.
		std::ostringstream index_expression_stream;
		index_expression_stream << "0";  // get things started
		
		
		boost::regex index_regex("\\]\\s*\\[");

		// split the index strings
        boost::sregex_token_iterator i_t(index_pattern.begin(),
									   index_pattern.end(),
									   index_regex, -1);
        boost::sregex_token_iterator j_t;
		
		vector<string> indices;
		while(i_t != j_t){
			indices.push_back(*i_t++);
		}

		if(indices.size() != stimulus_group->getNDimensions()) {
			throw FatalParserException("Illegal stimulus dimension reference", stem);			
		}
		
		for(unsigned int i = 0; i < indices.size(); i++){
			index_expression_stream << "+((" << boost::algorithm::trim_copy(indices.at(i)) << ")";
			
			for(unsigned int j = i + 1; j < indices.size(); j++){			
				index_expression_stream << "*("; 
				index_expression_stream << stimulus_group->dimensionSize(j);
				index_expression_stream << ")";
			}
			index_expression_stream << ")";
		}
		
		index_expression = index_expression_stream.str();
	} else {
		// if not multi-dimensional, the work is easier
		index_expression = index_pattern;
	}
	
    
    if(index_expression.empty()){
        FatalParserException f("Empty expression indexing stimulus group");
        f << stimulus_group_error_info(stimulus_group);
        throw f;
    }
    
    shared_ptr<Variable> index_var;
    
	// Parse the index expression
    try {
        index_var = getVariable(index_expression);
	
    } catch(UnknownExpressionException& e){
        
        FatalParserException f("Invalid index to stimulus group");
        f << expression_error_info(index_expression.c_str());
        
        throw f;
    }
    
	// Create a "node group" to go with the stimulus group
	//shared_ptr<StimulusNodeGroup> 
	//	stimulus_node_group(new StimulusNodeGroup(stimulus_group));
	
	// Create the relevant reference
	shared_ptr<StimulusGroupReferenceNode> 
				refnode(new StimulusGroupReferenceNode(stimulus_node_group, 
														index_var));
	
	return refnode;
}