SIRF  3.4.0
Parser.h
Go to the documentation of this file.
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2017 - 2019 University College London
4 
5 This is software developed for the Collaborative Computational
6 Project in Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR)
7 (http://www.ccpsynerbi.ac.uk/).
8 
9 Licensed under the Apache License, Version 2.0 (the "License");
10 you may not use this file except in compliance with the License.
11 You may obtain a copy of the License at
12 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 
19 */
20 
30 #pragma once
31 
32 #include "sirf/Reg/ParserKey.h"
33 #include <memory>
34 #include <map>
35 #include <fstream>
36 #include <boost/filesystem.hpp>
37 #include <type_traits>
38 
39 namespace sirf {
48 template<class Z>
49 class Parser
50 {
51 public:
52 
54  Parser() {}
55 
57  virtual ~Parser() {}
58 
60  void set_object(std::shared_ptr<Z> object) { _object = object; }
61 
63  void set_filename(std::string filename) { _filename = filename; }
64 
66  void add_key(const std::string &keyword, void (Z::*function)())
67  {
68  std::cout << "Adding a keyword to the list of possible parameters: " << keyword << "..." << std::flush;
69 
70  // Create a new key, then add keyword and function
71  std::shared_ptr<ParserKey0Arg<Z> > key = std::make_shared<ParserKey0Arg<Z> >();
72  key->set_object(_object);
73  key->set_function(function);
74  _keys[keyword] = key;
75 
76  std::cout << " done.\n" << std::flush;
77  }
78 
80  template<class Y, class A>
81  void add_key(const std::string &keyword, void (Y::*function)(A))
82  {
83  std::cout << "Adding a keyword to the list of possible parameters: " << keyword << "..." << std::flush;
84 
85  // Create a new key, then add keyword and function
86  std::shared_ptr<ParserKey1Arg<Z,A> > key = std::make_shared<ParserKey1Arg<Z,A> >();
87  key->set_object(_object);
88  key->set_function(function);
89  _keys[keyword] = key;
90 
91  std::cout << " done.\n" << std::flush;
92  }
93 
95  template<class Y, class A, class B>
96  void add_key(const std::string &keyword, void (Y::*function)(A, B))
97  {
98  std::cout << "Adding a keyword to the list of possible parameters: " << keyword << "..." << std::flush;
99 
100  // Create a new key, then add keyword and function
101  std::shared_ptr<ParserKey2Arg<Z,A,B> > key = std::make_shared<ParserKey2Arg<Z,A,B> >();
102  key->set_object(_object);
103  key->set_function(function);
104  _keys[keyword] = key;
105 
106  std::cout << " done.\n" << std::flush;
107  }
108 
110  void parse()
111  {
112  // Open file
113  std::ifstream file;
114  this->open_file(file);
115 
116  std::string line;
117 
118  // Do nothing with the first line (as this is the title)
119  this->get_line(file,line);
120 
121  // Keep in the while loop until break
122  while(true) {
123 
124  // Get next line
125  this->get_line(file,line);
126 
127  // If end was found, break
128  if (this->is_end(line)) break;
129 
130  // If no parameter was found (blank line or comment), continue
131  if (!this->contains_parameter(line)) continue;
132 
133  // Give info to user
134  std::cout << "\nReading the line: \"" << line << "\"...\n";
135 
136  // Get the keyword
137  std::string keyword = this->get_keyword(line);
138 
139  // Get the key that corresponds to the keyword
140  std::shared_ptr<ParserKeyBase<Z> > key;
141  key = this->get_key_sptr(keyword);
142 
143  // Figure out the variables from the line of text
144  key->get_arguments(line);
145 
146  // Call the function
147  key->call_function();
148  }
149 
150  // Close the file
151  file.close();
152  }
153 
155  void open_file(std::ifstream &file)
156  {
157  // Open file
158  file.open(_filename);
159 
160  // Check file is open
161  if (!file) {
162  file.close();
163  throw std::runtime_error("Unable to open registration parameter file:\n\t" + _filename);
164  }
165 
166  std::cout << "\nSuccessfully opened the parameter file: " << _filename << "\n";
167  }
168 
170  void get_line(std::ifstream &file, std::string &line)
171  {
172  // If end of file was reached (this shouldn't happen, as the end statement in the
173  // parameter file should cause a break in the while loop before this gets called
174  if (!getline(file,line)) {
175  file.close();
176  throw std::runtime_error("Error reading parameter file. Maybe the end of the file was reached but no \"End\" statement was found.");
177  }
178 
179  // Take out any spaces and tabs
180  line.erase(remove(line.begin(),line.end(),' '),line.end());
181  line.erase(remove(line.begin(),line.end(),'\t'),line.end());
182 
183  // Remove everything to the right of the comment (if there is one)
184  line = line.substr(0, line.find(';'));
185 
186  }
187 
189  bool is_end(std::string line)
190  {
191  // Convert to lower case
192  std::transform(line.begin(), line.end(), line.begin(), ::tolower);
193 
194  // If first three characters are "end", return true
195  if (line.substr(0,3) == "end") {
196  std::cout << "\nThe end line was reached. Parsing will stop.\n\n";
197  return true;
198  }
199 
200  // Else, return false
201  return false;
202  }
203 
205  bool contains_parameter(std::string &line)
206  {
207  // If no ":=" is found, return false
208  if (line.find(":=") == -1) return false;
209 
210  return true;
211  }
212 
214  std::string get_keyword(std::string &line)
215  {
216  // get index of the ":="
217  auto index_end = line.find(":=");
218 
219  std::string keyword = line.substr(0, index_end);
220 
221  std::cout << "\tKeyword: " << keyword << "\n";
222 
223  // return the substring
224  return line.substr(0, index_end);
225  }
226 
228  std::shared_ptr<ParserKeyBase<Z> > get_key_sptr(std::string &keyword)
229  {
230  // Compare the keyword to the list of keys
231  typename std::map<std::string, std::shared_ptr<ParserKeyBase<Z> > >::iterator it;
232  it = _keys.find(keyword);
233 
234  // If the keyword is not found in the list of keys, display error & go to next line.
235  if (it == _keys.end()) {
236  throw std::runtime_error("Error. Key not found in list of possible keywords.");
237  }
238 
239  // If the keyword was found, print it
240  std::cout << "\tMatching key was found.\n";
241 
242  // Get the key
243  return it->second;
244  }
245 
246 protected:
248  std::shared_ptr<Z> _object;
250  std::string _filename;
252  std::map<std::string, std::shared_ptr<ParserKeyBase<Z> > > _keys;
253 };
254 }
std::string get_keyword(std::string &line)
Get the keyword from a line.
Definition: Parser.h:214
virtual ~Parser()
Destructor.
Definition: Parser.h:57
void set_object(std::shared_ptr< Z > object)
Set object.
Definition: Parser.h:60
Parser keys for 0, 1 and 2 arguments.
void set_filename(std::string filename)
Set filename.
Definition: Parser.h:63
void add_key(const std::string &keyword, void(Z::*function)())
Add key with 0 arguments.
Definition: Parser.h:66
std::shared_ptr< ParserKeyBase< Z > > get_key_sptr(std::string &keyword)
Get a key from its keyword.
Definition: Parser.h:228
Definition: Parser.h:49
void parse()
Parse.
Definition: Parser.h:110
std::shared_ptr< Z > _object
Object.
Definition: Parser.h:248
std::map< std::string, std::shared_ptr< ParserKeyBase< Z > > > _keys
Map of keys.
Definition: Parser.h:252
bool contains_parameter(std::string &line)
Does the line contain a parameter?
Definition: Parser.h:205
Abstract data container.
Definition: GeometricalInfo.cpp:141
Parser()
Constructor.
Definition: Parser.h:54
void add_key(const std::string &keyword, void(Y::*function)(A, B))
Add key with 2 arguments - we need to template Y in case Z is the derived class and Y is a parent cla...
Definition: Parser.h:96
std::string _filename
Filename.
Definition: Parser.h:250
void get_line(std::ifstream &file, std::string &line)
Get line.
Definition: Parser.h:170
bool is_end(std::string line)
Is the end of the file?
Definition: Parser.h:189
void open_file(std::ifstream &file)
Open file.
Definition: Parser.h:155
void add_key(const std::string &keyword, void(Y::*function)(A))
Add key with 1 argument - we need to template Y in case Z is the derived class and Y is a parent clas...
Definition: Parser.h:81