Follow this link to skip to the main content

claraty::Parameter_Parser Class Reference
[Core Package]

#include <parameter_parser.h>

Collaboration diagram for claraty::Parameter_Parser:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 Parameter_Parser (const char *pfile)
 Parameter_Parser (std::string pfile)
 ~Parameter_Parser ()
Mechanism_Model_Param_Parser parse tree query
int get_int (const char *vname)
double get_double (const char *vname)
bool get_bool (const char *vname)
const char * get_string (const char *vname)
const pug::xml_node document () const
bool has_tag_name (std::string itname)
bool has_attribute_match (pug::xml_node &node, const std::string attribute_name, const std::string attribute_value)
bool get_bool_from_attribute_value (const char *vname)
void attribute_values_by_name (const std::string attribute_names[], pug::xml_node &node_element, int n_attributes, std::string attribute_values[])
void attribute_value_by_name (const std::string attribute_name, pug::xml_node &node_element, std::string &attribute_value)
void attributes_by_name (pug::xml_attribute attributes[], pug::xml_node &node_element, int n_attributes, const std::string attribute_names[])
double evaluate_expression (pug::xml_attribute &var_val)
int evaluate_expression_int (pug::xml_attribute &var_val)

Static Public Attributes

static const int ID_LENGTH = 31
static const int TOKEN_LENGTH = 80
static const int ID_ERROR_MESSAGE_LENGTH = 256

Protected Types

enum  TOK_TYPES {
  DELIMITER, IDENTIFIER, NUMBER, KEYWORD,
  TEMP, STRING
}
enum  TOKENS {
  ARG, CHAR, INT, DOUBLE,
  STR, IF, ELSE, EOL,
  FINISHED, END
}
enum  DOUBLE_OPS {
  LT = 1, LE, GT, GE,
  EQ, NE
}
enum  ERROR_CODE {
  SYNTAX, UNBALANCED_PARENTHESIS, NO_EXPRESSION, NOT_A_VARIABLE,
  PARENTHESIS_EXPECTED, QUOTE_EXPECTED, NOT_A_STRING, NOT_A_NUMERIC,
  BAD_TYPE, CIRCULAR_REFERENCE
}

Protected Member Functions

pug::xml_node _get_variable (const char *vname)
double _get_double (pug::xml_node &variable)
double _evaluate_expression (pug::xml_node &variable)
void _eval_exp (double *value)
void _eval_exp0 (double *value)
void _eval_exp1 (double *value)
void _eval_exp2 (double *value)
void _eval_exp3 (double *value)
void _eval_exp4 (double *value)
void _eval_exp5 (double *value)
void _atom (double *value)
double _fetch_var_value (const char *vname)
void _sntx_err (int error, const char *s=0)
int _get_token (void)
void _putback (void)
int _get_internal_function_index (char *s)
int _get_internal_constant_index (char *s)
int _isdelim (char c)
bool _is_pending (const char *vname)
int _iswhite (char c)
int _is_var (char *vname)
std::string _remove_white_space (const std::string white_space_str)
double _call_C_function (double(*fcn)(double))

Protected Attributes

pug::xml_parser_xml
unsigned long _parser_options
char _token [TOKEN_LENGTH]
char _token_type
char _tok
char * _prog
char * _pfile_name
const char * _current_var
std::list< std::string > _pending

Static Protected Attributes

static struct _constants_table_type _constants_table []
static struct _intern_func_type _intern_func []

Classes

struct  _constants_table_type
struct  _intern_func_type
struct  Parser_Error

Detailed Description

Parameter Parser

Definition at line 39 of file parameter_parser.cc.


Member Enumeration Documentation

Enumerator:
DELIMITER 
IDENTIFIER 
NUMBER 
KEYWORD 
TEMP 
STRING 

Definition at line 100 of file parameter_parser.h.

Enumerator:
ARG 
CHAR 
INT 
DOUBLE 
STR 
IF 
ELSE 
EOL 
FINISHED 
END 

Definition at line 101 of file parameter_parser.h.

00101 {ARG, CHAR, INT, DOUBLE, STR, IF, ELSE, EOL, FINISHED, END};

Enumerator:
LT 
LE 
GT 
GE 
EQ 
NE 

Definition at line 102 of file parameter_parser.h.

00102 {LT=1, LE, GT, GE, EQ, NE};

Enumerator:
SYNTAX 
UNBALANCED_PARENTHESIS 
NO_EXPRESSION 
NOT_A_VARIABLE 
PARENTHESIS_EXPECTED 
QUOTE_EXPECTED 
NOT_A_STRING 
NOT_A_NUMERIC 
BAD_TYPE 
CIRCULAR_REFERENCE 

Definition at line 109 of file parameter_parser.h.


Constructor & Destructor Documentation

claraty::Parameter_Parser::Parameter_Parser ( const char *  pfile  ) 

Definition at line 132 of file parameter_parser.cc.

References _parser_options, _pfile_name, _token, _xml, pug::parse_comments, pug::parse_doctype, pug::xml_parser::parse_file(), pug::parse_pi, pug::parse_trim_attribute, pug::parse_trim_comment, pug::parse_trim_pcdata, and pug::parse_wnorm.

00132                                                     :
00133    _xml(0), _token_type(0), _tok(0), _prog(0),
00134    _pfile_name(0), _current_var(0)
00135 {
00136   //cout << "Creating Parameter_Parser("
00137   //      << pfile << ")" << endl;
00138    
00139    bzero(_token, sizeof(_token));
00140    
00141    char buff[256];
00142    // Save a copy of the file name
00143    _pfile_name = new char[strlen(pfile)+1];
00144    if(!_pfile_name) {
00145       sprintf(buff, "Could not allocate memory for string \"%s\"", pfile);
00146       throw Parser_Error(0, buff);
00147    }
00148    strcpy(_pfile_name, pfile);
00149    
00150    // create the xml parser to parse the parameter file
00151    _xml = new xml_parser();
00152    if(!_xml) {
00153       sprintf(buff, "Could not allocate memory for XML parser.");
00154       throw Parser_Error(0, buff);
00155    }
00156    
00157    _parser_options =        
00158       parse_doctype        | //Parse '<!DOCTYPE ...>' section, with '[...]' as data member.
00159       parse_pi             | //Parse '<?...?>'
00160       parse_comments       | //Parse <!--...-->'
00161       parse_wnorm          | //Normalize all entities that are flagged to be trimmed.
00162       parse_trim_attribute | //Trim 'foo="..."'.
00163       parse_trim_pcdata    | //Trim '>...<'
00164       parse_trim_comment;    //Trim <!--...-->'
00165    
00166    if(!_xml->parse_file(pfile, _parser_options)) {
00167       // file not found. Then throw an exception
00168       sprintf(buff, "File %s not found", pfile);
00169       throw Parser_Error(0, buff);
00170    }
00171    //cout << "Parser created" << endl;
00172 }

Here is the call graph for this function:

claraty::Parameter_Parser::Parameter_Parser ( std::string  pfile  ) 

Definition at line 82 of file parameter_parser.cc.

References _parser_options, _pfile_name, _token, _xml, pug::parse_comments, pug::parse_doctype, pug::parse_pi, pug::parse_trim_attribute, pug::parse_trim_comment, pug::parse_trim_pcdata, and pug::parse_wnorm.

00083 {
00084   //cout << "Creating Parameter_Parser("
00085   //      << pfile.c_str() << ")" << endl;
00086    
00087    bzero(_token, sizeof(_token));
00088    
00089    char buff[256];
00090    // Save a copy of the file name
00091    _pfile_name = new char[strlen(pfile.c_str())+1];
00092    if(!_pfile_name) {
00093       sprintf(buff, "Could not allocate memory for string \"%s\"", pfile.c_str());
00094       throw Parser_Error(0, buff);
00095    }
00096    strcpy(_pfile_name, pfile.c_str());
00097    
00098    // create the xml parser to parse the parameter file
00099    _xml = new xml_parser();
00100    if(!_xml) {
00101       sprintf(buff, "Could not allocate memory for XML parser.");
00102       throw Parser_Error(0, buff);
00103    }
00104    
00105    _parser_options =        
00106       parse_doctype        | //Parse '<!DOCTYPE ...>' section, with '[...]' as data member.
00107       parse_pi             | //Parse '<?...?>'
00108       parse_comments       | //Parse <!--...-->'
00109       parse_wnorm          | //Normalize all entities that are flagged to be trimmed.
00110       parse_trim_attribute | //Trim 'foo="..."'.
00111       parse_trim_pcdata    | //Trim '>...<'
00112       parse_trim_comment;    //Trim <!--...-->'
00113    
00114    if(!_xml->parse_file(pfile.c_str(), _parser_options)) {
00115       // file not found. Then throw an exception
00116       sprintf(buff, "File %s not found", pfile.c_str());
00117       throw Parser_Error(0, buff);
00118    }
00119    //cout << "Parser created" << endl;
00120 }

claraty::Parameter_Parser::~Parameter_Parser (  ) 

Definition at line 177 of file parameter_parser.cc.

References _pfile_name, and _xml.

00178 {
00179   if(_xml != NULL) {
00180     delete _xml;
00181     _xml = 0;
00182   }
00183   if(_pfile_name) {
00184     delete [] _pfile_name;
00185   }
00186 }


Member Function Documentation

int claraty::Parameter_Parser::get_int ( const char *  vname  ) 

Definition at line 297 of file parameter_parser.cc.

References _current_var, _get_double(), and _get_variable().

00298 {
00299    try {
00300       _current_var = vname;
00301       xml_node variable = _get_variable(vname);
00302       return (int) _get_double(variable);
00303    } catch(Parser_Error) {
00304       throw; // re-throw the exception
00305    }
00306 }

Here is the call graph for this function:

double claraty::Parameter_Parser::get_double ( const char *  vname  ) 

Definition at line 320 of file parameter_parser.cc.

References _current_var, _get_double(), and _get_variable().

00321 {
00322    try {
00323       _current_var = vname;
00324       xml_node variable = _get_variable(vname);
00325       return _get_double(variable);
00326    } catch(Parser_Error) {
00327       throw;
00328    }
00329 }

Here is the call graph for this function:

bool claraty::Parameter_Parser::get_bool ( const char *  vname  ) 

Definition at line 400 of file parameter_parser.cc.

References _current_var, _get_variable(), _sntx_err(), pug::xml_node::attribute(), BAD_TYPE, pug::xml_node::empty(), pug::xml_attribute::has_value(), and NOT_A_VARIABLE.

00401 {
00402    try {
00403       _current_var = vname;
00404       xml_node variable = _get_variable(vname);
00405       if(!variable.empty()) {
00406          if(!variable.attribute("type").has_value("bool"))
00407             _sntx_err(BAD_TYPE);
00408          return (bool) variable.attribute("val");
00409       } else {
00410          // variable not found. Fail
00411          _sntx_err(NOT_A_VARIABLE);
00412       }
00413    } catch(Parser_Error) {
00414       throw;
00415    }
00416    return false;
00417 }

Here is the call graph for this function:

const char * claraty::Parameter_Parser::get_string ( const char *  vname  ) 

Definition at line 345 of file parameter_parser.cc.

References _current_var, _get_variable(), _sntx_err(), pug::xml_node::attribute(), pug::xml_node::empty(), pug::xml_attribute::has_value(), NOT_A_STRING, and NOT_A_VARIABLE.

00346 {
00347    try {
00348       _current_var = vname;
00349       xml_node variable = _get_variable(vname);
00350       if(!variable.empty()) {
00351          if(!variable.attribute("type").has_value("string"))
00352             _sntx_err(NOT_A_STRING);
00353          return (const char*) variable.attribute("val");
00354       } else {
00355          // variable not found. Fail
00356          _sntx_err(NOT_A_VARIABLE);
00357       }
00358    } catch(Parser_Error) {
00359       throw;
00360    }
00361    return vname;
00362 }

Here is the call graph for this function:

const pug::xml_node claraty::Parameter_Parser::document (  )  const [inline]

Definition at line 69 of file parameter_parser.h.

References _xml, and pug::xml_parser::document().

00069 { return _xml->document(); }

Here is the call graph for this function:

bool claraty::Parameter_Parser::has_tag_name ( std::string  itname  ) 

Return bool indicating if the tagname in itname is in the parse tree.

Returns:
TRUE if found, FALSE if not

Definition at line 196 of file parameter_parser.cc.

References _xml, pug::xml_parser::document(), pug::xml_node::empty(), and pug::xml_node::first_element_by_name().

00197 {
00198   pug::xml_node itelem = _xml->document().first_element_by_name(itname);
00199   return !itelem.empty();
00200 }

Here is the call graph for this function:

bool claraty::Parameter_Parser::has_attribute_match ( pug::xml_node node,
const std::string  attribute_name,
const std::string  attribute_value 
)

Return bool indicating if the tagname is the attribute corresponding to the attribute type among the children of the specified nodes..

Returns:
TRUE if found, FALSE if not

Definition at line 212 of file parameter_parser.cc.

References _T, pug::xml_node::attributes_begin(), and pug::xml_node::attributes_end().

Referenced by claraty::Mechanism_Model_IO::_extract_model_type().

00216 {
00217   //For each attribute.
00218   pug::xml_node::attribute_iterator jelem = node.attributes_begin();
00219   pug::xml_node::attribute_iterator nelem = node.attributes_end();
00220   for(; jelem != nelem; ++jelem)
00221   {
00222     if ( _T(jelem->name()) == attribute_name)   
00223       {
00224         if (jelem->value() == attribute_value)
00225           return true;
00226       }
00227   }
00228   return false;
00229 }

Here is the call graph for this function:

bool claraty::Parameter_Parser::get_bool_from_attribute_value ( const char *  vname  ) 

Return a bool value of an attribute value

Parameters:
[in] vname Char string containing attribute value.
Returns:
Bool value of attribute value

Definition at line 374 of file parameter_parser.cc.

00375 {
00376   try
00377   {
00378     if ((strcmp(vname, "true") == 0) ||(strcmp(vname, "yes") == 0))
00379       return true;
00380     else
00381       return false;
00382   }
00383   catch(Parser_Error)
00384   {
00385     throw;
00386   }
00387 }

void claraty::Parameter_Parser::attribute_values_by_name ( const std::string  attribute_names[],
pug::xml_node node_element,
int  n_attributes,
std::string  attribute_values[] 
)

Save a node's attribute values as strings for the given name

Parameters:
[in] node_element Reference to the node element.
[in] n_attributes Integer number of attributes.
[in] attribute_names Array of attribute names.
[in] attribute_values Array of strings to contain the attribute values.

Definition at line 661 of file parameter_parser.cc.

References attribute_value_by_name(), and pug::node_element.

Referenced by claraty::Transform_IO::_extract_DH_params_attributes(), claraty::Transform_IO::_extract_position_attributes(), claraty::Transform_IO::_extract_quaternion_attributes(), claraty::Transform_IO::_extract_rot_x_attributes(), claraty::Transform_IO::_extract_rot_y_attributes(), claraty::Transform_IO::_extract_rot_z_attributes(), claraty::Transform_IO::_extract_three_angle_set_attributes(), claraty::ME_Joint_IO::_joint_constraint_attributes(), claraty::ME_Joint_IO::_joint_limits_attributes(), claraty::ME_Joint_IO::_joint_stiffness_attributes(), claraty::Mass_Properties_IO::_set_inertia_attributes(), claraty::ME_Joint_IO::extract_from_parse_tree(), claraty::ME_Body_IO::extract_from_parse_tree(), claraty::Display_Graphics_IO::extract_from_parse_tree(), claraty::N_3D_Object_IO::extract_from_parse_tree(), claraty::Mass_Properties_IO::extract_from_parse_tree(), and claraty::Frame_IO::extract_from_parse_tree().

00666 {
00667   //For each attribute.
00668 
00669   for (int i_att=0; i_att<n_attributes; ++i_att)
00670     attribute_value_by_name(attribute_names[i_att],
00671                             node_element,
00672                             attribute_values[i_att]);
00673 }

Here is the call graph for this function:

void claraty::Parameter_Parser::attribute_value_by_name ( const std::string  attribute_name,
pug::xml_node node_element,
std::string &  attribute_value 
)

void claraty::Parameter_Parser::attributes_by_name ( pug::xml_attribute  attributes[],
pug::xml_node node_element,
int  n_attributes,
const std::string  attribute_names[] 
)

Save a node's attributes

Parameters:
[in] node_element Reference to the node element.
[in] n_attributes Integer number of attributes.
[in] attribute_names Array of attribute names.
[in] attributes Array of attributes.

Definition at line 687 of file parameter_parser.cc.

References _T, and pug::node_element.

Referenced by claraty::Transform_IO::_extract_DH_params_attributes(), claraty::Transform_IO::_extract_position_attributes(), claraty::Transform_IO::_extract_quaternion_attributes(), claraty::Transform_IO::_extract_rot_x_attributes(), claraty::Transform_IO::_extract_rot_y_attributes(), claraty::Transform_IO::_extract_rot_z_attributes(), claraty::Transform_IO::_extract_three_angle_set_attributes(), claraty::ME_Joint_IO::_joint_limits_attributes(), claraty::ME_Joint_IO::_joint_stiffness_attributes(), claraty::Mass_Properties_IO::_set_inertia_attributes(), claraty::ME_Joint_IO::extract_from_parse_tree(), claraty::Bounding_Shape_IO::extract_from_parse_tree(), claraty::N_3D_Object_IO::extract_from_parse_tree(), and claraty::Mass_Properties_IO::extract_from_parse_tree().

00691 {
00692   //For each attribute.
00693   pug::xml_node::attribute_iterator jelem = node_element.attributes_begin(); 
00694   pug::xml_node::attribute_iterator nelem = node_element.attributes_end();
00695   for(; jelem != nelem; ++jelem)
00696   {
00697     for (int i_att=0; i_att<n_attributes; i_att++)
00698     {
00699       // Register attribute
00700       if ( _T(jelem->name()) == attribute_names[i_att])         
00701         attributes[i_att] = *jelem;
00702     }
00703 
00704   }
00705 }

double claraty::Parameter_Parser::evaluate_expression ( pug::xml_attribute var_val  ) 

Evaluate the expression to a double value

Parameters:
[in] var_val Reference to the attribute to be evaluated.
Returns:
Double value of expression

Definition at line 716 of file parameter_parser.cc.

References _eval_exp(), _prog, _tok, _token, _token_type, TOKEN_LENGTH, and pug::xml_attribute::value().

Referenced by claraty::Transform_IO::_extract_DH_params_attributes(), claraty::ME_Joint_IO::_joint_limits_attributes(), claraty::ME_Joint_IO::_joint_stiffness_attributes(), evaluate_expression_int(), claraty::ME_Joint_IO::extract_from_parse_tree(), and claraty::Mass_Properties_IO::extract_from_parse_tree().

00717 {
00718   // save current parser state
00719   char tmp_token[TOKEN_LENGTH];                // string representation of token
00720   char tmp_token_type = _token_type; // contains type of token 
00721   char tmp_tok = _tok;               // internal representation of token 
00722   char *tmp_prog = _prog;            // current location in source code
00723   strcpy(tmp_token, _token);
00724   
00725 #if DEBUG_PPARSER       
00726   cout << endl << "in evaluate_expression()" << _prog << endl;
00727 #endif
00728   // set the pointers to start parsing
00729   _prog = (char*) var_val.value();
00730   
00731 #if DEBUG_PPARSER       
00732   cout << endl << "_evaluate_expression::_prog = " << _prog << endl;
00733 #endif
00734   
00735   double result = 0;
00736   try {
00737     _eval_exp(&result);
00738   } catch(Parser_Error) {
00739     throw;
00740   }
00741   //recover parser state before returning
00742   _token_type = tmp_token_type;
00743   _tok = tmp_tok;
00744   _prog = tmp_prog;
00745   strcpy(_token, tmp_token);
00746   return result;
00747 }

Here is the call graph for this function:

int claraty::Parameter_Parser::evaluate_expression_int ( pug::xml_attribute var_val  ) 

Evaluate an integer expression

Parameters:
[in] var_val Attribute to be evaluated.
Returns:
Integer value of expression

Definition at line 759 of file parameter_parser.cc.

References evaluate_expression().

00761 {
00762   return (int)evaluate_expression(var_val);
00763 }

Here is the call graph for this function:

xml_node claraty::Parameter_Parser::_get_variable ( const char *  vname  )  [protected]

Definition at line 451 of file parameter_parser.cc.

References _xml, pug::xml_node::attribute(), pug::xml_node::attributes(), pug::xml_node::child(), pug::xml_node::children(), pug::xml_parser::document(), pug::xml_node::empty(), pug::xml_node::first_element_by_attribute(), pug::xml_node::first_element_by_path(), pug::xml_node::has_attribute(), pug::xml_node::has_name(), and pug::xml_node::parent().

Referenced by _fetch_var_value(), _is_var(), get_bool(), get_double(), get_int(), and get_string().

00452 {
00453    // if vname has no "." then 
00454    //   Search for any tag having '<var name="vname">'.  and return
00455    //   the entry found or the empty node if variable not found.
00456    // if vname includes "." then
00457    //   it locates the subtree at the end of the path. It then searches
00458    //   the subtree for any tag having '<var name="vname">'.
00459    char* path = new char[strlen(vname)+2];
00460    strcpy(path, vname);
00461    char* rdelim = strrchr(path, '.'); // get last occurrence of '.'
00462    char* fdelim = strchr(path, '.');  // get first occurrence of '.'
00463    xml_node node;
00464    
00465    if(rdelim == NULL) {
00466       // no path given so search for the first occurrence of vname
00467       // this still supports the old file definition. This uses a
00468       // Depth-First-Search so order in the pfile matters if we are
00469       // using absolute paths and the old method to get the
00470       // variable
00471       node = _xml->document().first_element_by_attribute("var", "name", vname);
00472 
00473       // compute absolute path
00474       for(register short i = strlen(path); i >= 0; i--)
00475          path[i+1] = path[i];
00476       path[0] = '.';
00477    } else {
00478       // There are '.' in the variable name so we must have an
00479       // absolute path. Therefore the first occurrence of '.'  (i.e.,
00480       // the root of the path) must be the first element in path
00481       if(fdelim == path) {
00482          if(rdelim == fdelim) {
00483             // a varible is being referred from the root (i.e.: .var)
00484             node = _xml->document(); // start from the root
00485             register int nchild = node.children(); // get the number of children of the root
00486             for(register int j = 0; j < nchild; ++j) {
00487                if(node.child(j).has_name("var")) { // is this a variable?
00488                   // check if it has the variable name that we are looking for     
00489                   node = node.child(j); // Move to this child.
00490                   
00491                   // get number of attributes of this variable
00492                   register unsigned int nattr = node.attributes(); 
00493                   for(register unsigned int i = 0; i < nattr; ++i) {
00494                      xml_attribute attr = node.attribute(i);
00495                      if(attr.has_name("name") && attr.has_value(rdelim+1)) {
00496                         goto terminate;
00497                      }
00498                   }
00499                   // pop up one level
00500                   node = node.parent();
00501                }
00502             }
00503             // not found. set node to the empty node
00504             node = xml_node();
00505          } else {
00506             *rdelim = 0;
00507             // get the node representing the last subtree in the path
00508             node = _xml->document().first_element_by_path(path, ".");            
00509             if(!node.empty()) {
00510                node = node.first_element_by_attribute("var", "name", rdelim+1);
00511             }
00512             *rdelim = '.';
00513          }
00514       }
00515    }
00516    if(!node.empty() && !node.has_attribute("abs_path")) {
00517       // set the absolute path for this variable
00518       node.attribute("abs_path") = path;
00519    }
00520 
00521  terminate:
00522    delete[] path;
00523    return node;
00524 }

Here is the call graph for this function:

double claraty::Parameter_Parser::_get_double ( pug::xml_node variable  )  [protected]

Definition at line 538 of file parameter_parser.cc.

References _current_var, _evaluate_expression(), _pending, _prog, _sntx_err(), _tok, _token, _token_type, pug::xml_node::attribute(), BAD_TYPE, pug::xml_node::empty(), pug::xml_node::has_attribute(), pug::xml_attribute::has_value(), NOT_A_VARIABLE, and pug::xml_attribute::value().

Referenced by _fetch_var_value(), get_double(), and get_int().

00539 {
00540    try {
00541       if(!variable.empty()) {        
00542          if(!variable.attribute("type").has_value("double") &&
00543             !variable.attribute("type").has_value("int")) {
00544             // cannot evaluate a string as a double
00545             _sntx_err(BAD_TYPE);
00546          }
00547 
00548          // save the current var so it can be restored later
00549          const char* old_var = _current_var;
00550          
00551          // re-set current variable name
00552          _current_var = variable.attribute("abs_path").value();
00553          
00554 #if DEBUG_PPARSER       
00555          cout << "\nget_double: " << variable.attribute("name").value();
00556 #endif
00557          // save current parser state
00558          char tmp_token[80];                // string representation of token
00559          char tmp_token_type = _token_type; // contains type of token 
00560          char tmp_tok = _tok;               // internal representation of token 
00561          char *tmp_prog = _prog;            // current location in source code
00562          strcpy(tmp_token, _token);
00563         
00564          // check if the expression has been evaluated. If it has then get
00565          // the value. it it has not then evaluate and store the value
00566          double r;
00567          if(variable.has_attribute("eval_to")) {
00568             r = (double) variable.attribute("eval_to");
00569 #if DEBUG_PPARSER       
00570             cout << "...cached";
00571 #endif
00572          } else {
00573 #if DEBUG_PPARSER       
00574             cout << "...evaluation";
00575 #endif
00576             // push in the stack the current variable being evaluated
00577             _pending.push_back(string(variable.attribute("abs_path").value()));
00578 
00579             // evaluate the variable
00580             r = _evaluate_expression(variable);
00581 
00582             // store the variable value in the eval_to attribute
00583             if(variable.attribute("type").has_value("int")) {
00584               r = rint(r);
00585               //r = (double) ((int) (r+0.5));
00586             }
00587 
00588             variable.attribute("eval_to") = r;
00589 
00590 #if DEBUG_PARSER
00591             cout << variable;
00592 #endif
00593             // pop the variable off the stack
00594             _pending.pop_back();
00595 
00596          }
00597 #if DEBUG_PPARSER       
00598          cout << endl;
00599 #endif
00600 
00601          //recover parser state before returning
00602          _token_type = tmp_token_type;
00603          _tok = tmp_tok;
00604          _prog = tmp_prog;
00605          strcpy(_token, tmp_token);
00606 
00607          // restore old var
00608          _current_var = old_var;
00609          
00610          return r;
00611       } else {
00612          // variable not found. Fail
00613          _sntx_err(NOT_A_VARIABLE);
00614       }
00615    } catch(Parser_Error) {
00616       throw;
00617    }
00618    return 0.0;
00619 }

Here is the call graph for this function:

double claraty::Parameter_Parser::_evaluate_expression ( pug::xml_node variable  )  [protected]

Definition at line 778 of file parameter_parser.cc.

References _eval_exp(), _prog, pug::xml_node::attribute(), and pug::xml_attribute::value().

Referenced by _get_double().

00779 {
00780    // get the expression to evaluate
00781    xml_attribute var_val = variable.attribute("val");
00782     
00783    // set the pointers to start parsing
00784    _prog = (char*) var_val.value();
00785 
00786 #if DEBUG_PPARSER       
00787    cout << endl << "_evaluate_expression::_prog = " << _prog << endl;
00788 #endif
00789 
00790    double result = 0;
00791    try {
00792       _eval_exp(&result);
00793    } catch(Parser_Error) {
00794       throw;
00795    }
00796    return result;
00797 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp ( double *  value  )  [protected]

Definition at line 811 of file parameter_parser.cc.

References _eval_exp0(), _get_token(), _putback(), _sntx_err(), _token, and NO_EXPRESSION.

Referenced by _call_C_function(), _evaluate_expression(), and evaluate_expression().

00812 {
00813    // start parsing the expression
00814    try {
00815       _get_token();
00816       if(!*_token) {
00817          _sntx_err(NO_EXPRESSION); 
00818          return;
00819       }
00820       _eval_exp0(value);
00821       _putback(); // return last token read to input stream
00822    } catch(Parser_Error) {
00823       throw;
00824    }
00825 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp0 ( double *  value  )  [protected]

Definition at line 839 of file parameter_parser.cc.

References _eval_exp1(), _get_token(), _is_var(), _putback(), _token, _token_type, ID_LENGTH, and IDENTIFIER.

Referenced by _eval_exp(), and _eval_exp5().

00840 {
00841    char temp[ID_LENGTH];  // holds name of var receiving the assignment
00842    register int temp_tok;
00843    try {
00844       if(_token_type==IDENTIFIER) {
00845          if(_is_var(_token)) {  // if a var, see if assignment
00846             strcpy(temp, _token);
00847             temp_tok = _token_type;
00848             _get_token();
00849             if(*_token=='=') {  // is an assignment
00850                _get_token();
00851                _eval_exp0(value);  // get value to assign
00852                //  _assign_var(temp, *value);  // assign the value (commented out for now)
00853                return;
00854             }
00855             else {  // not an assignment
00856                _putback();  // restore original token
00857                strcpy(_token, temp);
00858                _token_type = temp_tok;
00859             }
00860          }
00861       }
00862       _eval_exp1(value);
00863    } catch(Parser_Error) {
00864       throw;
00865    }
00866 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp1 ( double *  value  )  [protected]

Definition at line 880 of file parameter_parser.cc.

References _eval_exp2(), _get_token(), _token, EQ, GE, GT, LE, LT, and NE.

Referenced by _eval_exp0().

00881 {
00882    static char relops[7] = {
00883       LT, LE, GT, GE, EQ, NE, 0
00884    };
00885     
00886    try {
00887       _eval_exp2(value);
00888       register char op = *_token;
00889       
00890       if(strchr(relops, op)) {
00891          _get_token();
00892         
00893          double partial_value;
00894          _eval_exp2(&partial_value);
00895          switch(op) {  // perform the relational operation
00896          case LT:
00897             *value = *value < partial_value;
00898             break;
00899          case LE:
00900             *value = *value <= partial_value;
00901             break;
00902          case GT:
00903             *value = *value > partial_value;
00904             break;
00905          case GE:
00906             *value = *value >= partial_value;
00907             break;
00908          case EQ:
00909             *value = *value == partial_value;
00910             break;
00911          case NE:
00912             *value = *value != partial_value;
00913             break;
00914          }
00915       }
00916    } catch(Parser_Error) {
00917       throw;
00918    }
00919 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp2 ( double *  value  )  [protected]

Definition at line 933 of file parameter_parser.cc.

References _eval_exp3(), _get_token(), and _token.

Referenced by _eval_exp1().

00934 {
00935    register char  op;
00936    double partial_value;
00937 
00938    try {
00939       _eval_exp3(value);
00940       while((op = *_token) == '+' || op == '-') {
00941          _get_token();
00942          _eval_exp3(&partial_value);
00943          switch(op) {  // add or subtract 
00944          case '-':
00945             *value = *value - partial_value;
00946             break;
00947          case '+':
00948             *value = *value + partial_value;
00949             break;
00950          }
00951       }
00952    } catch(Parser_Error) {
00953       throw;
00954    }
00955 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp3 ( double *  value  )  [protected]

Definition at line 969 of file parameter_parser.cc.

References _eval_exp4(), _get_token(), and _token.

Referenced by _eval_exp2().

00970 {
00971    register char  op;
00972    double partial_value, t;
00973 
00974    try {
00975       _eval_exp4(value);
00976       while((op = *_token) == '*' || op == '/' || op == '%') {
00977          _get_token();
00978          _eval_exp4(&partial_value);
00979          switch(op) { // mul, div, or modulus
00980          case '*':
00981             *value = *value * partial_value;
00982             break;
00983          case '/':
00984             *value = (*value) / partial_value;
00985             break;
00986          case '%':
00987             t = (*value) / partial_value;
00988             *value = *value-(t * partial_value);
00989             break;
00990          }
00991       }
00992    } catch(Parser_Error) {
00993       throw;
00994    }
00995 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp4 ( double *  value  )  [protected]

Definition at line 1009 of file parameter_parser.cc.

References _eval_exp5(), _get_token(), and _token.

Referenced by _eval_exp3().

01010 {
01011    register char  op = '\0';
01012     
01013    try {
01014       if(*_token=='+' || *_token=='-') {
01015          op = *_token;
01016          _get_token();
01017       }
01018       _eval_exp5(value);
01019       if(op)
01020          if(op=='-') *value = -(*value);
01021    } catch(Parser_Error) {
01022       throw;
01023    }
01024 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_eval_exp5 ( double *  value  )  [protected]

Definition at line 1038 of file parameter_parser.cc.

References _atom(), _eval_exp0(), _get_token(), _sntx_err(), _token, and UNBALANCED_PARENTHESIS.

Referenced by _eval_exp4().

01039 {
01040    try {
01041       if((*_token == '(')) {
01042          _get_token();
01043          _eval_exp0(value);   // get subexpression
01044          if(*_token != ')') 
01045             _sntx_err(UNBALANCED_PARENTHESIS);
01046          _get_token();
01047       }
01048       else
01049          _atom(value);
01050    } catch(Parser_Error) {
01051       throw;
01052    }
01053 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_atom ( double *  value  )  [protected]

Definition at line 1067 of file parameter_parser.cc.

References _call_C_function(), _constants_table, _fetch_var_value(), _get_internal_constant_index(), _get_internal_function_index(), _get_token(), _intern_func, _prog, _sntx_err(), _token, _token_type, DELIMITER, IDENTIFIER, NUMBER, QUOTE_EXPECTED, SYNTAX, and claraty::Parameter_Parser::_constants_table_type::val.

Referenced by _eval_exp5().

01068 {
01069    int i;
01070    try {
01071       switch(_token_type) {
01072       case IDENTIFIER:
01073          i = _get_internal_function_index(_token);
01074          if(i!= -1) {  // call "standard library" function
01075             //            *value = (this->*_intern_func[i].p)();
01076             *value = _call_C_function(_intern_func[i].fcn);
01077          } else {
01078             i = _get_internal_constant_index(_token);
01079             if(i != -1) { // we've got an internal constant e.g., M_PI
01080                *value = _constants_table[i].val;
01081             } else {
01082                *value = _fetch_var_value(_token); // get var's value from XML tree
01083             }
01084          }
01085          _get_token();
01086          return;
01087       case NUMBER: // is numeric constant
01088          *value = atof(_token);
01089          _get_token();
01090          return;
01091       case DELIMITER: // see if character constant
01092          if(*_token=='\'') {
01093             *value = *_prog;
01094             _prog++;
01095             if(*_prog!='\'') 
01096                _sntx_err(QUOTE_EXPECTED); 
01097             _prog++;
01098             _get_token();
01099          }
01100          return;
01101       default:
01102          if(*_token==')') return; // process empty expression
01103          else _sntx_err(SYNTAX); // syntax error
01104       }
01105    } catch(Parser_Error) {
01106       throw;
01107    }
01108 }

Here is the call graph for this function:

double claraty::Parameter_Parser::_fetch_var_value ( const char *  vname  )  [protected]

Definition at line 1123 of file parameter_parser.cc.

References _get_double(), _get_variable(), _is_pending(), _sntx_err(), pug::xml_node::attribute(), BAD_TYPE, CIRCULAR_REFERENCE, pug::xml_node::empty(), pug::xml_attribute::has_value(), NOT_A_NUMERIC, NOT_A_VARIABLE, and pug::xml_attribute::value().

Referenced by _atom().

01124 {
01125    try {
01126       // locate the variable
01127       xml_node variable = _get_variable(vname);
01128       if(!variable.empty()) {
01129          // look in the stack of pending variables to see if the variable
01130          // is in. If it is then we have detected a circular reference
01131          if(_is_pending(variable.attribute("abs_path").value()))
01132             _sntx_err(CIRCULAR_REFERENCE);
01133          
01134          // evaluate it
01135          xml_attribute type = variable.attribute("type");
01136          if(type.has_value("int") || type.has_value("double"))
01137             return _get_double(variable);
01138          else if(type.has_value("string") || type.has_value("bool"))
01139             _sntx_err(NOT_A_NUMERIC);
01140          else // unknown type
01141             _sntx_err(BAD_TYPE);
01142       } else {
01143          _sntx_err(NOT_A_VARIABLE, vname);
01144       }
01145    } catch(Parser_Error) {
01146       throw;
01147    }
01148    return 0.0;
01149 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_sntx_err ( int  error,
const char *  s = 0 
) [protected]

Definition at line 1164 of file parameter_parser.cc.

References _current_var, _pending, _pfile_name, and CIRCULAR_REFERENCE.

Referenced by _atom(), _call_C_function(), _eval_exp(), _eval_exp5(), _fetch_var_value(), _get_double(), _get_token(), get_bool(), and get_string().

01165 {
01166    static char *e[]= {
01167       "syntax error",
01168       "unbalanced parentheses",
01169       "no expression present",
01170       "variable not found",
01171       "parentheses expected",
01172       "closing quote expected",
01173       "not a string",
01174       "cannot eval string to a number",
01175       "invalid data type",
01176       "circular reference in expression"
01177    };
01178    char msg[256];
01179    if(s) {
01180       sprintf(msg, "In file %s:\nError while parsing <var name=%s/> -- %s: %s", 
01181               _pfile_name, _current_var, e[error], s);
01182    } else {
01183       sprintf(msg, "In file %s:\nError while parsing <var name=%s/> -- %s", 
01184               _pfile_name, _current_var, e[error]);
01185       if(error == CIRCULAR_REFERENCE) {
01186          strcat(msg, "\nCycle:\n");
01187          list<string>::const_iterator iter;
01188          char str[256];
01189          for(iter = _pending.begin(); iter != _pending.end(); iter++) {
01190             sprintf(str, "\t%s\n", (*iter).c_str());
01191             strcat(msg, str);
01192          }
01193       }
01194    }
01195    throw Parser_Error(error+1, msg);
01196 }

int claraty::Parameter_Parser::_get_token ( void   )  [protected]

Definition at line 1209 of file parameter_parser.cc.

References _isdelim(), _iswhite(), _prog, _sntx_err(), _tok, _token, _token_type, DELIMITER, EQ, FINISHED, GE, GT, IDENTIFIER, LE, LT, NE, NUMBER, STRING, and SYNTAX.

Referenced by _atom(), _call_C_function(), _eval_exp(), _eval_exp0(), _eval_exp1(), _eval_exp2(), _eval_exp3(), _eval_exp4(), and _eval_exp5().

01210 {
01211    register char* temp;
01212    _token_type = 0; 
01213    _tok = 0;
01214    temp = _token;
01215    *temp = '\0';
01216     
01217    // skip over white space
01218    while(_iswhite(*_prog) && *_prog) ++_prog;
01219    if(*_prog=='\r') {
01220       ++_prog;
01221       ++_prog;
01222       // skip over white space
01223       while(_iswhite(*_prog) && *_prog) ++_prog;
01224    }
01225    if(*_prog=='\0') { // end of file
01226       *_token = '\0';
01227       _tok = FINISHED;
01228       return(_token_type=DELIMITER);
01229    }
01230    /* look for comments */
01231    if(*_prog=='/')
01232       if(*(_prog+1)=='*') { /* is a comment */
01233          _prog += 2;
01234          do { /* find end of comment */
01235             while(*_prog!='*') _prog++;
01236             _prog++;
01237          } while (*_prog!='/');
01238          _prog++;
01239       }
01240    if(strchr("!<>=", *_prog)) { // is or might be a relation operator
01241       switch(*_prog) {
01242       case '=': 
01243          if(*(_prog+1)=='=') {
01244             _prog++; _prog++;
01245             *temp = EQ;
01246             temp++; *temp = EQ; 
01247             temp++;
01248             *temp = '\0';
01249          }
01250          break;
01251       case '!': 
01252          if(*(_prog+1)=='=') {
01253             _prog++; _prog++;
01254             *temp = NE;
01255             temp++; *temp = NE; temp++;
01256             *temp = '\0';
01257          }
01258          break;
01259       case '<': 
01260          if(*(_prog+1)=='=') {
01261             _prog++; _prog++;
01262             *temp = LE; temp++; *temp = LE;
01263          }
01264          else {
01265             _prog++;
01266             *temp = LT;
01267          }
01268          temp++;
01269          *temp = '\0';
01270          break;
01271       case '>': 
01272          if(*(_prog+1)=='=') {
01273             _prog++; _prog++;
01274             *temp = GE; temp++; *temp = GE;
01275          }
01276          else {
01277             _prog++;
01278             *temp = GT;
01279          }
01280          temp++;
01281          *temp = '\0';
01282          break;
01283       }
01284       if(*_token) 
01285          return(_token_type = DELIMITER);
01286    }
01287    if(strchr("+-*^/%=;(),'", *_prog)) { // delimiter
01288       *temp = *_prog;
01289       _prog++; // advance to next position
01290       temp++;
01291       *temp = '\0';
01292       return (_token_type=DELIMITER);
01293    }
01294    if(*_prog=='"') { // quoted string
01295       _prog++;
01296       while(*_prog!='"'&& *_prog!='\r') *temp++ = *_prog++;
01297       if(*_prog=='\r') _sntx_err(SYNTAX);
01298       _prog++; 
01299       *temp = '\0';
01300       return(_token_type=STRING);
01301    }
01302    if(isdigit(*_prog)) { // number: digit+ [. digit+]
01303       //      while(!isdelim(*_prog)) *temp++ = *_prog++;
01304       while(isdigit(*_prog)) *temp++ = *_prog++;
01305       if(*_prog == '.') {
01306          *temp++ = *_prog++;
01307          while(isdigit(*_prog)) *temp++ = *_prog++;
01308       }
01309       if(tolower(*_prog) == 'e') {
01310          *temp++ = *_prog++;
01311          if(*_prog == '-' || *_prog == '+') {
01312             *temp++ = *_prog++;
01313          }
01314          while(!_isdelim(*_prog)) *temp++ = *_prog++;
01315       }
01316 
01317       *temp = '\0';
01318       return(_token_type = NUMBER);
01319    }
01320    if(isalpha(*_prog) || *_prog == '.') { // var or command
01321       while(!_isdelim(*_prog)) *temp++ = *_prog++;
01322       _token_type=IDENTIFIER;
01323    }
01324    *temp = '\0';
01325    return _token_type;
01326 }

Here is the call graph for this function:

void claraty::Parameter_Parser::_putback ( void   )  [inline, protected]

Definition at line 246 of file parameter_parser.cc.

References _prog, and _token.

Referenced by _eval_exp(), and _eval_exp0().

00247 {
00248    char *t;
00249    t = _token;
00250    for(; *t; t++) _prog--;
00251 }

int claraty::Parameter_Parser::_get_internal_function_index ( char *  s  )  [inline, protected]

Definition at line 256 of file parameter_parser.cc.

References _intern_func, and claraty::Parameter_Parser::_intern_func_type::f_name.

Referenced by _atom().

00257 {
00258    int i;
00259    for(i=0; _intern_func[i].f_name[0]; i++) {
00260       if(!strcmp(_intern_func[i].f_name, s))  return i;
00261    }
00262    return -1;
00263 }

int claraty::Parameter_Parser::_get_internal_constant_index ( char *  s  )  [inline, protected]

Definition at line 268 of file parameter_parser.cc.

References _constants_table, and claraty::Parameter_Parser::_constants_table_type::cname.

Referenced by _atom().

00269 {
00270    int i;
00271    for(i=0; _constants_table[i].cname[0]; i++) {
00272       if(!strcmp(_constants_table[i].cname, s))  return i;
00273    }
00274    return -1;
00275 }

int claraty::Parameter_Parser::_isdelim ( char  c  )  [inline, protected]

Definition at line 280 of file parameter_parser.cc.

Referenced by _get_token().

00281 {
00282    return((int) strchr(" !;,+-<>'/*%^=()", c) || c==9 || c=='\r' || c==0);
00283 }

bool claraty::Parameter_Parser::_is_pending ( const char *  vname  )  [inline, protected]

Definition at line 235 of file parameter_parser.cc.

References _pending.

Referenced by _fetch_var_value().

00236 {
00237    list<string>::const_iterator iter;
00238 
00239    iter = find(_pending.begin(), _pending.end(), string(vname)); // Search the list.
00240    return(iter != _pending.end());
00241 }

int claraty::Parameter_Parser::_iswhite ( char  c  )  [inline, protected]

Definition at line 169 of file parameter_parser.h.

Referenced by _get_token().

00169 { return(c==' ' || c=='\t'); }

int claraty::Parameter_Parser::_is_var ( char *  vname  )  [inline, protected]

Definition at line 172 of file parameter_parser.h.

References _get_variable(), and pug::xml_node::empty().

Referenced by _eval_exp0().

00172 { return !_get_variable(vname).empty(); }

Here is the call graph for this function:

std::string claraty::Parameter_Parser::_remove_white_space ( const std::string  white_space_str  )  [protected]

Remove white space in a string

Parameters:
[in] white_space_str String to be processed.
Returns:
String without white space

Definition at line 1338 of file parameter_parser.cc.

01340 {
01341   // Make a copy of the string
01342   std::string clean_str = white_space_str;
01343 
01344   // Remove spaces
01345   while (clean_str.find(" ", 0) != std::string::npos)
01346   {
01347     size_t  pos = clean_str.find(" ", 0); 
01348                 clean_str.erase(pos, 1); 
01349   }
01350 
01351   // Remove tabs
01352   while (clean_str.find("\t", 0) != std::string::npos)
01353   {
01354                 size_t  pos = clean_str.find("\t", 0); 
01355                 clean_str.erase(pos, 1); 
01356   }
01357           
01358   return clean_str;
01359 }

double claraty::Parameter_Parser::_call_C_function ( double(*)(double)  fcn  )  [protected]

Definition at line 1377 of file parameter_parser.cc.

References _eval_exp(), _get_token(), _sntx_err(), _token, and PARENTHESIS_EXPECTED.

Referenced by _atom().

01378 {
01379    double res;
01380 
01381    try {
01382       _get_token();
01383       if(*_token != '(')
01384          _sntx_err(PARENTHESIS_EXPECTED);
01385       double arg;
01386       _eval_exp(&arg);
01387       res = (*fcn)(arg);
01388       _get_token();
01389       if(*_token != ')')
01390          _sntx_err(PARENTHESIS_EXPECTED);
01391       return res;
01392    } catch(Parser_Error) {
01393       throw;
01394    }
01395 }

Here is the call graph for this function:


Member Data Documentation

const int claraty::Parameter_Parser::ID_LENGTH = 31 [static]

Definition at line 45 of file parameter_parser.h.

Referenced by _eval_exp0().

const int claraty::Parameter_Parser::TOKEN_LENGTH = 80 [static]

Definition at line 46 of file parameter_parser.h.

Referenced by evaluate_expression().

Definition at line 47 of file parameter_parser.h.

unsigned long claraty::Parameter_Parser::_parser_options [protected]

Definition at line 124 of file parameter_parser.h.

Referenced by Parameter_Parser().

Definition at line 127 of file parameter_parser.h.

Referenced by _get_double(), _get_token(), and evaluate_expression().

Definition at line 129 of file parameter_parser.h.

Referenced by _sntx_err(), Parameter_Parser(), and ~Parameter_Parser().

const char* claraty::Parameter_Parser::_current_var [protected]

Definition at line 130 of file parameter_parser.h.

Referenced by _get_double(), _sntx_err(), get_bool(), get_double(), get_int(), and get_string().

Definition at line 132 of file parameter_parser.h.

Referenced by _atom(), and _get_internal_constant_index().

Definition at line 133 of file parameter_parser.h.

Referenced by _atom(), and _get_internal_function_index().

std::list<std::string> claraty::Parameter_Parser::_pending [protected]

Definition at line 135 of file parameter_parser.h.

Referenced by _get_double(), _is_pending(), and _sntx_err().


The documentation for this class was generated from the following files: