All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Parser.cpp
Go to the documentation of this file.
1 // $Id:$
2 // ============================================================================
3 // STD:
4 // ============================================================================
5 #include <fstream>
6 // ============================================================================
7 // BOOST:
8 // ============================================================================
9 #include <boost/format.hpp>
10 #include <boost/filesystem.hpp>
11 // ============================================================================
12 #include "Parser.h"
13 #include "Messages.h"
14 #include "Node.h"
15 #include "Grammar.h"
16 #include "Iterator.h"
17 #include "IncludedFiles.h"
18 #include "Utils.h"
19 // ============================================================================
20 // Gaudi:
21 // ============================================================================
23 // ============================================================================
24 namespace classic = boost::spirit::classic;
25 namespace bf = boost::filesystem;
26 namespace gp= Gaudi::Parsers;
27 namespace gpu= Gaudi::Parsers::Utils;
28 namespace qi = boost::spirit::qi;
29 // ============================================================================
30 namespace {
31 // ============================================================================
32 void GetLastLineAndColumn(std::ifstream& ifs, int& line, int& column) {
33  int n = 0;
34  std::string str;
35  while(!ifs.eof()) {
36  getline(ifs, str);
37  n++;
38  }
39  line = n;
40  column = str.length()+1;
41  ifs.clear();
42  ifs.seekg(0, ifs.beg);
43 }
44 
45 template<typename Grammar>
46 bool ParseStream(std::ifstream& stream,
47  const std::string& stream_name, gp::Messages* messages,
48  gp::Node* root) {
49 
50  int last_line, last_column;
51 
52 
53  GetLastLineAndColumn(stream, last_line, last_column);
54 
55  std::string input((std::istreambuf_iterator<char>(stream)),
56  std::istreambuf_iterator<char>());
57 
58  BaseIterator in_begin(input.begin());
59  // convert input iterator to forward iterator, usable by spirit parser
60  ForwardIterator fwd_begin =
61  boost::spirit::make_default_multi_pass(in_begin);
62  ForwardIterator fwd_end;
63 
64  // wrap forward iterator with position iterator, to record the position
65 
66  Iterator position_begin(fwd_begin, fwd_end, stream_name);
67  Iterator position_end;
68 
69  Grammar gr;
70  gp::SkipperGrammar<Iterator> skipper;
71 
72  root->value = stream_name;
73  bool result = qi::phrase_parse(position_begin,
74  position_end, gr, skipper, *root);
75 
76  const IteratorPosition& pos = position_begin.get_position();
77  if (result && (pos.line == last_line) && (pos.column == last_column)) {
78  return true;
79  }
80 
81  messages->AddError(gp::Position(stream_name, pos.line,
82  pos.column),"parse error");
83  return false;
84 }
85 
86 // ============================================================================
87 template<typename Grammar>
88 bool ParseFile(const gp::Position& from, const std::string& filename,
89  const std::string& search_path,
90  gp::IncludedFiles* included, gp::Messages* messages,gp::Node* root) {
91  std::string search_path_with_current_dir =
92  gpu::replaceEnvironments(search_path);
93  if (!from.filename().empty()) { // Add current file directory to search_path
94  bf::path file_path(from.filename());
95  search_path_with_current_dir = file_path.parent_path().string()
96  + (search_path_with_current_dir.empty()?""
97  :("," + search_path_with_current_dir));
98  }
99  std::string absolute_path = System::PathResolver::find_file_from_list(
100  gpu::replaceEnvironments(filename), search_path_with_current_dir);
101 
102  if (absolute_path.empty()) {
103  messages->AddError(from, "Couldn't find a file " + filename+
104  " in search path '"+ search_path_with_current_dir+"'");
105  return false;
106  }
107  const gp::Position* included_from;
108  if (!included->GetPosition(absolute_path, &included_from)){
109  included->AddFile(absolute_path, from);
110  std::ifstream file(absolute_path.c_str());
111  if (!file.is_open()) {
112  messages->AddError(from, "Couldn't open a file "+filename);
113  return false;
114  }
115  return ParseStream<Grammar>(file, absolute_path, messages, root);
116  } else {
117  assert(included_from != NULL);
118  messages->AddWarning(from,
119  str(boost::format("File %1% already included from %2%")
120  % absolute_path % included_from->ToString()));
121  return true;
122  }
123 }
124 // ============================================================================
125 }
126 // ============================================================================
127 bool gp::Parse(const std::string& filename,
128  const std::string& search_path, IncludedFiles* included,
129  Messages* messages, Node* root){
130  return Parse(Position(), filename, search_path, included, messages,
131  root);
132 }
133 // ============================================================================
134 bool gp::Parse(const Position& from,
135  const std::string& filename,
136  const std::string& search_path, IncludedFiles* included,
137  Messages* messages, Node* root) {
139  return ParseFile<Grammar>(from, filename, search_path, included,
140  messages, root);
141 }
142 
143 // ============================================================================
144 bool gp::ParseUnits(const Position& from,
145  const std::string& filename,
146  const std::string& search_path, IncludedFiles* included,
147  Messages* messages, Node* root) {
149  return ParseFile<Grammar>(from, filename, search_path, included,
150  messages, root);
151 }
152 // ============================================================================
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:133
bool ParseUnits(const Position &from, const std::string &filename, const std::string &search_path, IncludedFiles *included, Messages *messages, Node *root)
Definition: Parser.cpp:144
static std::string find_file_from_list(const std::string &logical_file_name, const std::string &search_list, SearchType search_type=LocalSearch)
std::string::const_iterator BaseIterator
Definition: Iterator.h:17
std::string replaceEnvironments(const std::string &input)
Definition: Utils.cpp:26
boost::spirit::multi_pass< BaseIterator > ForwardIterator
Definition: Iterator.h:18
bool Parse(const std::string &filename, const std::string &search_path, IncludedFiles *included, Messages *messages, Node *root)
Definition: Parser.cpp:127
list file
Definition: ana.py:160
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
Definition: Iterator.h:19
tuple root
Definition: IOTest.py:42
boost::spirit::classic::file_position_base< std::string > IteratorPosition
Definition: Iterator.h:21
int line
Definition: ana.py:50