Limbo 3.5.4
Loading...
Searching...
No Matches
TfParser.h
Go to the documentation of this file.
1
7
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"
25using std::cout;
26using std::endl;
27using std::vector;
28using std::string;
29using std::ostringstream;
30using boost::int8_t;
31using boost::int32_t;
32using boost::int64_t;
33using boost::uint8_t;
34using boost::array;
35
36namespace qi = boost::spirit::qi;
37namespace ascii = boost::spirit::ascii;
38namespace spirit = boost::spirit;
39namespace 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
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 =
112 ;
113 block_defn = lexeme[TF_NO_CASE("layerDefinitions")]
114 >> lit("(")
115 >> *(
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 };
176
178 template <typename Iterator>
179 struct SkipperGrammar : qi::grammar<Iterator>
180 {
181 qi::rule<Iterator> skip;
182
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 };
195
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
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
error handler for Boost.Spirit parser
#define TF_NO_CASE(X)
an option to control case insensitivity
Definition TfParser.h:45
namespace for Limbo.Geometry
Definition Geometry.h:21
error handler
grammar of skipper
Definition TfParser.h:180
SkipperGrammar()
constructor
Definition TfParser.h:184
qi::rule< Iterator > skip
grammar to skip text
Definition TfParser.h:181
Base class for tf database. Only pure virtual functions are defined. User needs to inheritate this ...
Definition TfParser.h:62
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 grammar
Definition TfParser.h:77
qi::rule< Iterator, Skipper > block_display
technology display
Definition TfParser.h:82
qi::rule< Iterator, Skipper > expression
expression
Definition TfParser.h:78
qi::rule< Iterator, Skipper > block_layer_id
layer id
Definition TfParser.h:80
TfGrammar(DataBaseType &db, ErrorHandler< Iterator > &error_handler)
constructor
Definition TfParser.h:91
qi::rule< Iterator, string(), Skipper > text_nc
no constraints
Definition TfParser.h:84
qi::rule< Iterator, Skipper > block_defn
layer definitions
Definition TfParser.h:79
qi::rule< Iterator, Skipper > block_layer_purpose
layer purpose
Definition TfParser.h:81
void layer_id_cbk(string const &s1, int32_t const &d2, string const &s3)
callback of layer id
Definition TfParser.h:171
qi::rule< Iterator, string(), Skipper > text
text
Definition TfParser.h:83
DataBaseType & m_db
reference to database
Definition TfParser.h:86
Tf parser for technology file.
Definition TfParser.h:53
static bool read(DataBaseType &db, const string &tfFile)
API to read tf file.
Definition TfParser.h:199