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       delete base_node_;
00084       
00085       throw ParserException(error);
00086     }
00087   }
00088   
00094   bool Parser::eliminateFilenames(Node* n)
00095   {
00096     if(n->value != "")
00097     {  
00098       return true;
00099     }
00100     for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00101     {
00102       if(n->elements[i]->tag == "filename")
00103       { 
00104         if(!n->elements[i]->checkForFilename(n->tag))
00105         {
00106           std::string error = 
00107             std::string("STDR parser : ") + n->tag + std::string(" has a \
00108 filename of wrong type specified\n") + 
00109             std::string("\nError was in line ") + SSTR( n->file_row ) + 
00110             std::string(" of file '") + n->file_origin + std::string("'");
00111           throw ParserException(error);
00112         }
00113         Node* child = n->elements[i]->elements[0];
00114         n->elements.erase(n->elements.begin() + i);
00115         for(unsigned int j = 0 ; j < child->elements.size() ; j++)
00116         {
00117           child->elements[j]->increasePriority() ;
00118           n->elements.push_back(child->elements[j]);
00119         }
00120         return false;
00121       }
00122       else
00123       {
00124         try
00125         {
00126           if(!eliminateFilenames(n->elements[i]))
00127           {
00128             return false;
00129           }
00130         }
00131         catch(ParserException ex)
00132         {
00133           throw ex;
00134         }
00135       }
00136     }
00137     return true;
00138   }
00139   
00145   void Parser::mergeNodesValues(Node* n)
00146   {
00148     bool pure_values = true;
00149     for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00150     {
00151       if(n->elements[i]->value == "")
00152       {
00153         pure_values = false;
00154         break;
00155       }
00156     }
00157     
00158     if(pure_values)
00159     {
00161       if(n->elements.size() <= 1)
00162       {
00163         return;
00164       }
00165       
00167       int min_priority = n->elements[0]->priority;
00168       unsigned int index = 0;
00169       for(unsigned int i = 1 ; i < n->elements.size() ; i++)
00170       {
00171         if(n->elements[i]->priority < min_priority)
00172         {
00173           min_priority = n->elements[i]->priority;
00174           index = i;
00175         }
00176       }
00177       Node* proper_child = n->elements[index];
00178       n->elements.clear();
00179       n->elements.push_back(proper_child);
00180     }
00181     else
00182     {
00183       for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00184       {
00185         mergeNodesValues(n->elements[i]);
00186       }
00187     }
00188   }
00189 
00195   bool Parser::mergeNodes(Node* n)
00196   {
00197     if(n->value != "")  
00198     {
00199       return true;
00200     }
00201     for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00202     {
00204       if(n->elements[i]->value != "") 
00205       {
00206         continue;
00207       }
00208       std::string tag = n->elements[i]->tag;
00209       
00211       if(Specs::non_mergable_tags.find(tag) == Specs::non_mergable_tags.end())
00212       {
00213         std::vector<int> num = n->getTag(tag);
00214         
00216         if(num.size() != 1) 
00217         { 
00218           for(int i = num.size()-1 ; i > 0 ; i --)
00219           {
00221             for (unsigned int j = 0 ; 
00222               j < n->elements[num[i]]->elements.size() ; j++)
00223             {
00224               n->elements[num[0]]->elements.push_back(
00225                 n->elements[num[i]]->elements[j]);
00226             }
00227             n->elements.erase(n->elements.begin() + num[i]);
00228           }
00229           return false;
00230         }
00231       }
00232       
00233       if(!mergeNodes(n->elements[i]))
00234       {
00235         return false;
00236       }
00237     }
00238     return true;
00239   }
00240 }
00241 


stdr_parser
Author(s): Manos Tsardoulias, Chris Zalidis, Aris Thallas
autogenerated on Tue Feb 7 2017 03:46:27