| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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 // ============================================================================
22 #include "GaudiKernel/PathResolver.h"
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) {
138 typedef FileGrammar<Iterator,SkipperGrammar<Iterator> > Grammar;
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) {
148 typedef UnitsGrammar<Iterator,SkipperGrammar<Iterator> > Grammar;
149 return ParseFile<Grammar>(from, filename, search_path, included,
150 messages, root);
151 }
152 // ============================================================================