Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TfParser.h
Go to the documentation of this file.
1 
8 #ifndef _TFPARSER_H
9 #define _TFPARSER_H
10 
11 #include <iostream>
12 #include <fstream>
13 #include <sstream>
14 #include <vector>
15 #include <cassert>
16 #include <boost/array.hpp>
17 #include <boost/cstdint.hpp>
18 #include <boost/algorithm/string.hpp>
19 #include <boost/spirit/include/qi.hpp>
20 #include <boost/spirit/include/qi_no_case.hpp>
21 #include <boost/spirit/include/phoenix.hpp>
22 #include <boost/spirit/include/phoenix_bind.hpp>
24 //#include "Gadget.h"
25 using std::cout;
26 using std::endl;
27 using std::vector;
28 using std::string;
29 using std::ostringstream;
30 using boost::int8_t;
31 using boost::int32_t;
32 using boost::int64_t;
33 using boost::uint8_t;
34 using boost::array;
35 
36 namespace qi = boost::spirit::qi;
37 namespace ascii = boost::spirit::ascii;
38 namespace spirit = boost::spirit;
39 namespace phoenix = boost::phoenix;
40 
42 #ifdef CASE_INSENSITIVE
43  #define TF_NO_CASE(X) no_case[X]
44 #else
45  #define TF_NO_CASE(X) X
46 #endif
47 
52 struct TfParser
53 {
61  struct TfDataBase
62  {
63  // required callbacks
68  virtual void add_tf_layer_id(string const& s1, int32_t const& s2, string const& s3) = 0;
69  };
70 
75  template <typename Iterator, typename Skipper, typename DataBaseType>
76  struct TfGrammar : qi::grammar<Iterator, Skipper>
77  {
78  qi::rule<Iterator, Skipper> expression;
79  qi::rule<Iterator, Skipper> block_defn;
80  qi::rule<Iterator, Skipper> block_layer_id;
81  qi::rule<Iterator, Skipper> block_layer_purpose;
82  qi::rule<Iterator, Skipper> block_display;
83  qi::rule<Iterator, string(), Skipper> text;
84  qi::rule<Iterator, string(), Skipper> text_nc;
85 
86  DataBaseType& m_db;
87 
91  TfGrammar(DataBaseType& db, ErrorHandler<Iterator>& error_handler) : TfGrammar::base_type(expression), m_db(db)
92  {
93  using qi::int_;
94  using qi::uint_;
95  using qi::double_;
96  using qi::char_;
97  using qi::_1;
98  using qi::_2;
99  using qi::_3;
100  using qi::_4;
101  using qi::_5;
102  using qi::_a;
103  using qi::lexeme;
104  using qi::no_case;
105  using spirit::repeat;
106  using spirit::as_string;
107  using spirit::lit;
108  using spirit::inf;
109 
110  expression =
111  *block_defn
112  ;
113  block_defn = lexeme[TF_NO_CASE("layerDefinitions")]
114  >> lit("(")
115  >> *(
116  block_layer_id
117  | block_layer_purpose
118  | block_display
119  )
120  >> lit(")")
121  ;
122  block_layer_id = lexeme[TF_NO_CASE("techLayers")]
123  >> lit("(")
124  >> *(
125  (lit("(") >> text >> int_ >> text > lit(")")) [boost::phoenix::bind(&TfGrammar::layer_id_cbk, this, _1, _2, _3)]
126  )
127  >> lit(")")
128  ;
129  block_layer_purpose = lexeme[TF_NO_CASE("techLayerPurposePriorities")]
130  >> lit("(")
131  >> *(
132  (lit("(") >> text >> text > lit(")"))
133  )
134  >> lit(")")
135  ;
136  block_display = lexeme[TF_NO_CASE("techDisplays")]
137  >> lit("(")
138  >> *(
139  (lit("(") >> text >> text >> text >> repeat(5)[char_] > lit(")"))
140  )
141  >> lit(")")
142  ;
143 
144  text = lexeme[(char_("a-zA-Z") >> *char_("a-zA-Z_0-9-"))];
145  text_nc = lexeme[+char_("a-zA-Z_0-9.-")]; // text no constraints
146 
148 #if (BOOST_VERSION/100)%1000 == 55
149  // following Error handler only works in boost 1.55.0
150  // and there will be compilation error for 1.56.0 and 1.57.0
151  // Error handling: on error in expr, call error_handler.
152  qi::on_error<qi::fail>(expression,
153  boost::phoenix::function<ErrorHandler<Iterator> >(error_handler)(
154  "Error! Expecting ", _4, _3));
155 #else
156  qi::on_error<qi::fail>(expression,
157  phoenix::ref(std::cout)
158  << phoenix::val("Error! Expecting ")
159  << _4
160  << " here: '"
161  << phoenix::construct<string>(_3, _2)
162  << phoenix::val("'\n")
163  );
164 #endif
165  }
166 
171  void layer_id_cbk(string const& s1, int32_t const& d2, string const& s3)
172  {
173  m_db.add_tf_layer_id(s1, d2, s3);
174  }
175  };
178  template <typename Iterator>
179  struct SkipperGrammar : qi::grammar<Iterator>
180  {
181  qi::rule<Iterator> skip;
182 
184  SkipperGrammar() : SkipperGrammar::base_type(skip)
185  {
186  using qi::char_;
187  using qi::eol;
188  using spirit::lit;
189 
190  skip = ascii::space
191  | (";" >> *(char_ - eol) >> eol )
192  ;
193  }
194  };
198  template <typename DataBaseType>
199  static bool read(DataBaseType& db, const string& tfFile)
200  {
201  std::ifstream in;
202 
203  in.open(tfFile.c_str(), std::ios::in);
204  if (!in.is_open())
205  {
206  cout << "Unable to open input file " << tfFile << endl;
207  return false;
208  }
209 
210  in.unsetf(std::ios::skipws); // No white space skipping!
211  string str = std::string(std::istreambuf_iterator<char>(in.rdbuf()),
212  std::istreambuf_iterator<char>());
213  string::const_iterator iter = str.begin();
214  string::const_iterator end = str.end();
215 
216  typedef SkipperGrammar<string::const_iterator> skip_type;
217  skip_type skip;
218  typedef ErrorHandler<string::const_iterator> error_handler_type;
219  error_handler_type error_handler (iter, end);
221 
222  //TitleWriter().print("parsing tf file", 50, "#");
223  //bool r = qi::phrase_parse(iter, end, lg, boost::spirit::ascii::space);
224  bool r = qi::phrase_parse(iter, end, lg, skip);
225  //TitleWriter().print((r && iter == end)? "parsing succeed" : "parsing failed", 50, "#");
226 
227  return r && iter == end;
228  }
229 };
230 
231 #endif
qi::rule< Iterator, string(), Skipper > text
text
Definition: TfParser.h:83
grammar of skipper
Definition: TfParser.h:179
qi::rule< Iterator, Skipper > block_defn
layer definitions
Definition: TfParser.h:79
static bool read(DataBaseType &db, const string &tfFile)
API to read tf file.
Definition: TfParser.h:199
SkipperGrammar()
constructor
Definition: TfParser.h:184
qi::rule< Iterator, Skipper > block_layer_id
layer id
Definition: TfParser.h:80
define grammar
Definition: TfParser.h:76
qi::rule< Iterator, Skipper > block_layer_purpose
layer purpose
Definition: TfParser.h:81
qi::rule< Iterator, string(), Skipper > text_nc
no constraints
Definition: TfParser.h:84
DataBaseType & m_db
reference to database
Definition: TfParser.h:86
Tf parser for technology file.
Definition: TfParser.h:52
qi::rule< Iterator, Skipper > expression
expression
Definition: TfParser.h:78
virtual void add_tf_layer_id(string const &s1, int32_t const &s2, string const &s3)=0
add layer name, layer id, layer abbreviation
#define TF_NO_CASE(X)
an option to control case insensitivity
Definition: TfParser.h:45
qi::rule< Iterator > skip
grammar to skip text
Definition: TfParser.h:181
error handler
Definition: ErrorHandler.h:23
Base class for tf database. Only pure virtual functions are defined. User needs to inheritate this cl...
Definition: TfParser.h:61
error handler for Boost.Spirit parser
namespace for Limbo.Geometry
Definition: Geometry.h:20
void layer_id_cbk(string const &s1, int32_t const &d2, string const &s3)
callback of layer id
Definition: TfParser.h:171
TfGrammar(DataBaseType &db, ErrorHandler< Iterator > &error_handler)
constructor
Definition: TfParser.h:91
qi::rule< Iterator, Skipper > block_display
technology display
Definition: TfParser.h:82