stdr_parser.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002    STDR Simulator - Simple Two DImensional Robot Simulator
00003    Copyright (C) 2013 STDR Simulator
00004    This program is free software; you can redistribute it and/or modify
00005    it under the terms of the GNU General Public License as published by
00006    the Free Software Foundation; either version 3 of the License, or
00007    (at your option) any later version.
00008    This program is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011    GNU General Public License for more details.
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software Foundation,
00014    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015    
00016    Authors : 
00017    * Manos Tsardoulias, etsardou@gmail.com
00018    * Aris Thallas, aris.thallas@gmail.com
00019    * Chris Zalidis, zalidis@gmail.com 
00020 ******************************************************************************/
00021 
00022 #include "stdr_parser/stdr_parser.h"
00023 
00024 namespace stdr_parser
00025 {
00026   
00028   Node* Parser::base_node_ = new Node();
00029   
00034   Parser::Parser(void)
00035   {
00036     
00037   }
00038 
00044   void Parser::parse(std::string file_name)
00045   {
00046     Parser::base_node_ = new Node();
00047     Parser::base_node_->tag = "STDR_Parser_Root_Node";
00048     
00049     // Must destroy prev tree
00050     try
00051     {
00052       if(file_name.find(".xml") != std::string::npos)
00053       {
00054         XmlParser::parse(file_name,base_node_);  
00055       }
00056       else if(file_name.find(".yaml") != std::string::npos)
00057       {
00058         YamlParser::parse(file_name,base_node_);
00059       }
00060       //~ base_node_->printParsedXml(base_node_,"");
00061       Validator::parseMergableSpecifications();
00062       
00063       while(!eliminateFilenames(base_node_));
00064       while(!mergeNodes(base_node_));
00065       mergeNodesValues(base_node_);
00066       
00067       Validator::validate(file_name, base_node_);
00068       
00070       //~ base_node_->printParsedXml(base_node_,"");
00071     }
00072     catch(ParserException ex)
00073     {
00074       throw ex;
00075     }
00076     catch(YAML::ParserException& e)
00077     {
00078       std::string error = 
00079         std::string("Failed to load file '") + 
00080         file_name + std::string("'") +
00081         std::string("\nError was '") + std::string(e.what());
00082       
00083       base_node_->unallocateChildren();
00084       delete base_node_;
00085       
00086       throw ParserException(error);
00087     }
00088   }
00089   
00095   bool Parser::eliminateFilenames(Node* n)
00096   {
00097     if(n->value != "")
00098     {  
00099       return true;
00100     }
00101     for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00102     {
00103       if(n->elements[i]->tag == "filename")
00104       { 
00105         if(!n->elements[i]->checkForFilename(n->tag))
00106         {
00107           std::string error = 
00108             std::string("STDR parser : ") + n->tag + std::string(" has a \
00109 filename of wrong type specified\n") + 
00110             std::string("\nError was in line ") + SSTR( n->file_row ) + 
00111             std::string(" of file '") + n->file_origin + std::string("'");
00112           throw ParserException(error);
00113         }
00114         Node* child = n->elements[i]->elements[0];
00115         n->elements.erase(n->elements.begin() + i);
00116         for(unsigned int j = 0 ; j < child->elements.size() ; j++)
00117         {
00118           child->elements[j]->increasePriority() ;
00119           n->elements.push_back(child->elements[j]);
00120         }
00121         return false;
00122       }
00123       else
00124       {
00125         try
00126         {
00127           if(!eliminateFilenames(n->elements[i]))
00128           {
00129             return false;
00130           }
00131         }
00132         catch(ParserException ex)
00133         {
00134           throw ex;
00135         }
00136       }
00137     }
00138     return true;
00139   }
00140   
00146   void Parser::mergeNodesValues(Node* n)
00147   {
00149     bool pure_values = true;
00150     for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00151     {
00152       if(n->elements[i]->value == "")
00153       {
00154         pure_values = false;
00155         break;
00156       }
00157     }
00158     
00159     if(pure_values)
00160     {
00162       if(n->elements.size() <= 1)
00163       {
00164         return;
00165       }
00166       
00168       int min_priority = n->elements[0]->priority;
00169       unsigned int index = 0;
00170       for(unsigned int i = 1 ; i < n->elements.size() ; i++)
00171       {
00172         if(n->elements[i]->priority < min_priority)
00173         {
00174           min_priority = n->elements[i]->priority;
00175           index = i;
00176         }
00177       }
00178       Node* proper_child = n->elements[index];
00179       n->elements.clear();
00180       n->elements.push_back(proper_child);
00181     }
00182     else
00183     {
00184       for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00185       {
00186         mergeNodesValues(n->elements[i]);
00187       }
00188     }
00189   }
00190 
00196   bool Parser::mergeNodes(Node* n)
00197   {
00198     if(n->value != "")  
00199     {
00200       return true;
00201     }
00202     for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00203     {
00205       if(n->elements[i]->value != "") 
00206       {
00207         continue;
00208       }
00209       std::string tag = n->elements[i]->tag;
00210       
00212       if(Specs::non_mergable_tags.find(tag) == Specs::non_mergable_tags.end())
00213       {
00214         std::vector<int> num = n->getTag(tag);
00215         
00217         if(num.size() != 1) 
00218         { 
00219           for(int i = num.size()-1 ; i > 0 ; i --)
00220           {
00222             for (unsigned int j = 0 ; 
00223               j < n->elements[num[i]]->elements.size() ; j++)
00224             {
00225               n->elements[num[0]]->elements.push_back(
00226                 n->elements[num[i]]->elements[j]);
00227             }
00228             n->elements.erase(n->elements.begin() + num[i]);
00229           }
00230           return false;
00231         }
00232       }
00233       
00234       if(!mergeNodes(n->elements[i]))
00235       {
00236         return false;
00237       }
00238     }
00239     return true;
00240   }
00241 }
00242 


stdr_parser
Author(s): Manos Tsardoulias, Chris Zalidis, Aris Thallas
autogenerated on Wed Sep 2 2015 03:36:18