| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# Parser.cpp

Go to the documentation of this file.

    00001 // $Id:$
    00002 // ============================================================================
    00003 // STD:
    00004 // ============================================================================
    00005 #include <fstream>
    00006 // ============================================================================
    00007 // BOOST:
    00008 // ============================================================================
    00009 #include <boost/format.hpp>
    00010 #include <boost/filesystem.hpp>
    00011 // ============================================================================
    00012 #include "Parser.h"
    00013 #include "Messages.h"
    00014 #include "Node.h"
    00015 #include "Grammar.h"
    00016 #include "Iterator.h"
    00017 #include "IncludedFiles.h"
    00018 #include "Utils.h"
    00019 // ============================================================================
    00020 // Gaudi:
    00021 // ============================================================================
    00022 #include "GaudiKernel/PathResolver.h"
    00023 // ============================================================================
    00024 namespace classic = boost::spirit::classic;
    00025 namespace bf = boost::filesystem;
    00026 namespace gp= Gaudi::Parsers;
    00027 namespace gpu= Gaudi::Parsers::Utils;
    00028 namespace qi = boost::spirit::qi;
    00029 // ============================================================================
    00030 namespace {
    00031 // ============================================================================
    00032 template<typename Grammar>
    00033 bool ParseStream(std::ifstream& stream,
    00034         const std::string& stream_name, gp::Messages* messages,
    00035                gp::Node* root) {
    00036     // iterate over stream input
    00037     BaseIterator in_begin(stream);
    00038     // convert input iterator to forward iterator, usable by spirit parser
    00039     ForwardIterator fwd_begin =
    00040             boost::spirit::make_default_multi_pass(in_begin);
    00041     ForwardIterator fwd_end;
    00042
    00043     // wrap forward iterator with position iterator, to record the position
    00044
    00045     Iterator position_begin(fwd_begin, fwd_end, stream_name);
    00046     Iterator position_end;
    00047
    00048     Grammar gr;
    00049     gp::SkipperGrammar<Iterator> skipper;
    00050
    00051     root->value = stream_name;
    00052     bool result = qi::phrase_parse(position_begin,
    00053             position_end, gr, skipper, *root);
    00054     if (result && (position_begin==position_end)) {
    00055         return true;
    00056     }
    00057     const IteratorPosition& pos = position_begin.get_position();
    00058     messages->AddError(gp::Position(stream_name, pos.line,
    00059             pos.column),"parse error");
    00060     return false;
    00061 }
    00062
    00063 // ============================================================================
    00064 template<typename Grammar>
    00065 bool ParseFile(const gp::Position& from, const std::string& filename,
    00066         const std::string& search_path,
    00067         gp::IncludedFiles* included, gp::Messages* messages,gp::Node* root) {
    00068   std::string search_path_with_current_dir =
    00069       gpu::replaceEnvironments(search_path);
    00070   if (!from.filename().empty()) { // Add current file directory to search_path
    00071     bf::path file_path(from.filename());
    00072     search_path_with_current_dir = file_path.parent_path().string()
    00073         + (search_path_with_current_dir.empty()?""
    00074                                         :("," + search_path_with_current_dir));
    00075   }
    00076   std::string absolute_path = System::PathResolver::find_file_from_list(
    00077       gpu::replaceEnvironments(filename), search_path_with_current_dir);
    00078
    00079   if (absolute_path.empty()) {
    00080     messages->AddError(from, "Couldn't find a file " + filename+
    00081         " in search path '"+ search_path_with_current_dir+"'");
    00082     return false;
    00083   }
    00084   const gp::Position* included_from;
    00085   if (!included->GetPosition(absolute_path, &included_from)){
    00086     included->AddFile(absolute_path, from);
    00087     std::ifstream file(absolute_path.c_str());
    00088     if (!file.is_open()) {
    00089       messages->AddError(from, "Couldn't open a file "+filename);
    00090       return false;
    00091     }
    00092     return ParseStream<Grammar>(file, absolute_path, messages, root);
    00093   } else {
    00094     assert(included_from != NULL);
    00095     messages->AddWarning(from,
    00096         str(boost::format("File %1% already included from %2%")
    00097     % absolute_path %  included_from->ToString()));
    00098     return true;
    00099   }
    00100 }
    00101 // ============================================================================
    00102 }
    00103 // ============================================================================
    00104 bool gp::Parse(const std::string& filename,
    00105         const std::string& search_path, IncludedFiles* included,
    00106         Messages* messages,  Node* root){
    00107     return Parse(Position(),  filename, search_path, included, messages,
    00108             root);
    00109 }
    00110 // ============================================================================
    00111 bool gp::Parse(const Position& from,
    00112         const std::string& filename,
    00113         const std::string& search_path, IncludedFiles* included,
    00114         Messages* messages, Node* root) {
    00115     typedef FileGrammar<Iterator,SkipperGrammar<Iterator> > Grammar;
    00116     return ParseFile<Grammar>(from, filename, search_path, included,
    00117             messages, root);
    00118 }
    00119
    00120 // ============================================================================
    00121 bool gp::ParseUnits(const Position& from,
    00122         const std::string& filename,
    00123         const std::string& search_path, IncludedFiles* included,
    00124         Messages* messages, Node* root) {
    00125     typedef UnitsGrammar<Iterator,SkipperGrammar<Iterator> > Grammar;
    00126     return ParseFile<Grammar>(from, filename, search_path, included,
    00127             messages, root);
    00128 }
    00129 // ============================================================================

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines