libpniio
nx/nxpath/parser.hpp
Go to the documentation of this file.
1 //
2 // (c) Copyright 2014 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpniio.
5 //
6 // libpniio is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpniio is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libpniio. If not, see <http://www.gnu.org/licenses/>.
18 // ===========================================================================
19 //
20 // Created on: Jun 10, 2014
21 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
22 //
23 #pragma once
24 #include "nxpath.hpp"
25 #include "insert.hpp"
26 
27 #include <boost/spirit/include/qi.hpp>
28 #include <boost/spirit/include/phoenix.hpp>
29 #include <boost/fusion/include/std_pair.hpp>
30 #include <utility>
31 
32 
33 namespace pni{
34 namespace io{
35 namespace nx{
36 
37 //add here an additional namespace to avoid namespace polution from the boost
38 //spirit framework.
39 namespace parsers{
40 
41 
42  //------------------------------------------------------------------------
50  template<typename ITERT>
51  struct id_parser : boost::spirit::qi::grammar<ITERT,pni::core::string()>
52  {
54  boost::spirit::qi::rule<ITERT,pni::core::string()> id_rule;
55 
59  id_parser() : id_parser::base_type(id_rule)
60  {
61  using namespace boost::spirit;
62  using namespace boost::phoenix;
63  id_rule = +qi::char_("-_a-zA-Z0-9");
64  }
65  };
66 
67  //-------------------------------------------------------------------------
74  template<typename ITERT>
75  struct dot_parser : boost::spirit::qi::grammar<ITERT,pni::core::string()>
76  {
77  boost::spirit::qi::rule<ITERT,pni::core::string()> dot_rule;
78 
79  dot_parser() : dot_parser::base_type(dot_rule)
80  {
81  using namespace boost::spirit;
82  using namespace boost::phoenix;
83  using qi::_1;
84  dot_rule = lit(".")[_val = "."]||lit(".")[_val += "."];
85  }
86  };
87 
88  //--------------------------------------------------------------------------
95 
100  template<typename ITERT>
104  struct element_parser : boost::spirit::qi::grammar<
105  ITERT,
106  boost::spirit::locals<
107  pni::core::string,
108  pni::core::string
109  >,
110  nxpath::element_type()
111  >
112  {
116  typedef boost::spirit::qi::rule<ITERT,pni::core::string()>
119  typedef boost::spirit::locals<pni::core::string,pni::core::string>
121 
124 
127 
129  boost::spirit::qi::rule< ITERT,locals_type,nxpath::element_type()>
131 
133  element_parser() : element_parser::base_type(element_rule)
134  {
135  using namespace boost::spirit;
136  using namespace boost::phoenix;
137  using qi::_1;
138 
139  //a name is basically nothing else than a simple Nexus identifier
140  name_rule = id_[_val = _1] | dots_[_val=_1];
141  //a classname must alwasy start with a :
142  class_rule = lit(":") > id_[_val = _1];
143 
144  element_rule = eps[_a = "", _b=""]>>(
145  name_rule[_a = _1] || class_rule[_b = _1]
146  )[_val = construct<element_type>(_a,_b)];
147  }
148 
149  };
150 
151  //-------------------------------------------------------------------------
158 
163  template<typename ITERT>
166  struct elements_parser : boost::spirit::qi::grammar<ITERT,nxpath::elements_type()>
167  {
169  boost::spirit::qi::rule<ITERT,nxpath::elements_type()> elements_rule;
172 
174  elements_parser() : elements_parser::base_type(elements_rule)
175  {
176  using namespace boost::spirit;
177  using namespace boost::phoenix;
178  //[push_back(_val,construct<nxpath::element_type>("/","NXroot"))]
179  elements_rule = (element_ % '/') >-lit("/");
180  }
181  };
182 
183 
184 
185  //------------------------------------------------------------------------
196  template<typename ITERT>
197  struct nxpath_parser : boost::spirit::qi::grammar<ITERT,
198  boost::spirit::locals
199  <
200  nxpath::elements_type,
201  pni::core::string
202  >,
203  nxpath()>
204  {
206  boost::spirit::qi::rule<ITERT,
207  boost::spirit::locals
208  <
210  pni::core::string
211  >,
213 
215  boost::spirit::qi::rule<ITERT,nxpath::element_type()> root_rule;
216 
219 
222 
223  //--------------------------------------------------------------------
229  nxpath_parser(const pni::core::string &fname="") :
230  nxpath_parser::base_type(nxpath_rule),
231  _filename(fname)
232  {
233  using namespace boost::spirit;
234  using namespace boost::phoenix;
235  using boost::spirit::qi::_1;
236  // using boost::phoenix::merge;
237  using boost::phoenix::ref;
238 
239  root_rule = lit("/")[_val = construct<nxpath::element_type>("/","NXroot")];
240  root_rule.name("root_rule");
241 #ifdef __clang__
242 #pragma clang diagnostic push
243 #pragma clang diagnostic ignored "-Wunsequenced"
244 #endif
245  nxpath_rule = eps[
246  //we start with an empty elements list
247  _a = construct<nxpath::elements_type>(),
248  //and we start with an empty attribute
249  _b="",
250  //finally we start with an empty path which holds
251  //only a single root element
252  _val = construct<nxpath>(boost::phoenix::ref(_filename),_a,_b),
253  //this is where we add the root element
254  push_back(_val,construct<nxpath::element_type>("/","NXroot"))
255  ]
256  >>
257  ( //parse the root element
258  root_rule[push_back(_a,_1)]
259  ||
260  element_rule[pni::io::nx::insert(_a,end(_a),begin(_1),end(_1))]
261  ||
262  //here we do the attribute part
263  (lit("@")>id_[_b=_1])
264  ) [_val = construct<nxpath>(boost::phoenix::ref(_filename),_a,_b)]
265  >eoi; //finally EOI is the terminal for the string
266 #ifdef __clang__
267 #pragma clang diagnostic pop
268 #endif
269  }
270 
271  private:
273  pni::core::string _filename;
274  };
275 
276  //------------------------------------------------------------------------
288  nxpath parse_path(const pni::core::string &input);
289 
290 //end of parser namespace
291 }
292 
293 //end of namespace
294 }
295 }
296 }
nxpath_parser(const pni::core::string &fname="")
constructor
Definition: nx/nxpath/parser.hpp:229
parser dots
Definition: nx/nxpath/parser.hpp:75
boost::spirit::qi::rule< ITERT, pni::core::string()> string_rule_type
string rule type
Definition: nx/nxpath/parser.hpp:117
std::list< element_type > elements_type
a list of subsequent objects
Definition: nxpath/nxpath.hpp:66
boost::phoenix::function< stl::insert > const insert
Definition: insert.hpp:101
Definition: spirit_container_traits.hpp:33
nxpath parse_path(const pni::core::string &input)
parser string to path
Definition: parser.cpp:38
parser for group elements
Definition: nx/nxpath/parser.hpp:104
boost::spirit::locals< pni::core::string, pni::core::string > locals_type
type for parser locals
Definition: nx/nxpath/parser.hpp:120
string_rule_type class_rule
rule for a class
Definition: nx/nxpath/parser.hpp:123
string_rule_type name_rule
rule for a single name
Definition: nx/nxpath/parser.hpp:122
element_parser< ITERT > element_
group element parser
Definition: nx/nxpath/parser.hpp:171
id_parser()
default constructor
Definition: nx/nxpath/parser.hpp:59
pni::core::string _filename
the filename part
Definition: nx/nxpath/parser.hpp:273
id_parser< ITERT > id_
rule for a path ID
Definition: nx/nxpath/parser.hpp:125
Definition: cbf_reader.hpp:41
boost::spirit::qi::rule< ITERT, pni::core::string()> id_rule
the major rule to parse an ID
Definition: nx/nxpath/parser.hpp:54
auto begin(const OTYPE< IMPID > &group) -> decltype(group.begin())
get iterator to first element
Definition: iterators.hpp:46
elements_parser< ITERT > element_rule
parser for a single element
Definition: nx/nxpath/parser.hpp:221
std::pair< pni::core::string, pni::core::string > element_type
object element (groupname:class)
Definition: nxpath/nxpath.hpp:64
dot_parser()
Definition: nx/nxpath/parser.hpp:79
id_parser< ITERT > id_
parser for an individual Nexus ID
Definition: nx/nxpath/parser.hpp:218
parser for a nexus path
Definition: nx/nxpath/parser.hpp:197
auto end(const OTYPE< IMPID > &group) -> decltype(group.end())
get iterator to last element
Definition: iterators.hpp:69
nexus identifier parser
Definition: nx/nxpath/parser.hpp:51
parser for group path
Definition: nx/nxpath/parser.hpp:166
boost::spirit::qi::rule< ITERT, boost::spirit::locals< nxpath::elements_type, pni::core::string >, nxpath()> nxpath_rule
rule for the path
Definition: nx/nxpath/parser.hpp:212
boost::spirit::qi::rule< ITERT, locals_type, nxpath::element_type()> element_rule
rule for a full group element
Definition: nx/nxpath/parser.hpp:130
boost::spirit::qi::rule< ITERT, nxpath::elements_type()> elements_rule
rule for the entire group portion
Definition: nx/nxpath/parser.hpp:169
boost::spirit::qi::rule< ITERT, pni::core::string()> dot_rule
Definition: nx/nxpath/parser.hpp:77
Nexus path class.
Definition: nxpath/nxpath.hpp:60
dot_parser< ITERT > dots_
rule to parse dots
Definition: nx/nxpath/parser.hpp:126
boost::spirit::qi::rule< ITERT, nxpath::element_type()> root_rule
rule for the root part of the path
Definition: nx/nxpath/parser.hpp:215
element_parser()
default constructor
Definition: nx/nxpath/parser.hpp:133
elements_parser()
default constructor
Definition: nx/nxpath/parser.hpp:174
nxpath::element_type element_type
a single path element type
Definition: nx/nxpath/parser.hpp:114