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>
29 using std::ostringstream;
36 namespace qi = boost::spirit::qi;
37 namespace ascii = boost::spirit::ascii;
38 namespace spirit = boost::spirit;
39 namespace phoenix = boost::phoenix;
42 #ifdef CASE_INSENSITIVE
43 #define TF_NO_CASE(X) no_case[X]
45 #define TF_NO_CASE(X) X
68 virtual void add_tf_layer_id(
string const& s1, int32_t
const& s2,
string const& s3) = 0;
75 template <
typename Iterator,
typename Skipper,
typename DataBaseType>
83 qi::rule<Iterator, string(), Skipper>
text;
84 qi::rule<Iterator, string(), Skipper>
text_nc;
105 using spirit::repeat;
106 using spirit::as_string;
113 block_defn = lexeme[
TF_NO_CASE(
"layerDefinitions")]
117 | block_layer_purpose
122 block_layer_id = lexeme[
TF_NO_CASE(
"techLayers")]
125 (lit(
"(") >> text >> int_ >> text > lit(
")")) [boost::phoenix::bind(&
TfGrammar::layer_id_cbk,
this, _1, _2, _3)]
129 block_layer_purpose = lexeme[
TF_NO_CASE(
"techLayerPurposePriorities")]
132 (lit(
"(") >> text >> text > lit(
")"))
136 block_display = lexeme[
TF_NO_CASE(
"techDisplays")]
139 (lit(
"(") >> text >> text >> text >> repeat(5)[char_] > lit(
")"))
144 text = lexeme[(char_(
"a-zA-Z") >> *char_(
"a-zA-Z_0-9-"))];
145 text_nc = lexeme[+char_(
"a-zA-Z_0-9.-")];
148 #if (BOOST_VERSION/100)%1000 == 55
153 boost::phoenix::function<ErrorHandler<Iterator> >(error_handler)(
154 "Error! Expecting ", _4, _3));
157 phoenix::ref(std::cout)
158 << phoenix::val(
"Error! Expecting ")
161 << phoenix::construct<string>(_3, _2)
162 << phoenix::val(
"'\n")
171 void layer_id_cbk(
string const& s1, int32_t
const& d2,
string const& s3)
173 m_db.add_tf_layer_id(s1, d2, s3);
178 template <
typename Iterator>
191 | (
";" >> *(char_ - eol) >> eol )
198 template <
typename DataBaseType>
199 static bool read(DataBaseType& db,
const string& tfFile)
203 in.open(tfFile.c_str(), std::ios::in);
206 cout <<
"Unable to open input file " << tfFile << endl;
210 in.unsetf(std::ios::skipws);
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();
219 error_handler_type error_handler (iter, end);
224 bool r = qi::phrase_parse(iter, end, lg, skip);
227 return r && iter == end;
qi::rule< Iterator, string(), Skipper > text
text
qi::rule< Iterator, Skipper > block_defn
layer definitions
static bool read(DataBaseType &db, const string &tfFile)
API to read tf file.
SkipperGrammar()
constructor
qi::rule< Iterator, Skipper > block_layer_id
layer id
qi::rule< Iterator, Skipper > block_layer_purpose
layer purpose
qi::rule< Iterator, string(), Skipper > text_nc
no constraints
DataBaseType & m_db
reference to database
Tf parser for technology file.
qi::rule< Iterator, Skipper > expression
expression
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
qi::rule< Iterator > skip
grammar to skip text
Base class for tf database. Only pure virtual functions are defined. User needs to inheritate this cl...
error handler for Boost.Spirit parser
namespace for Limbo.Geometry
void layer_id_cbk(string const &s1, int32_t const &d2, string const &s3)
callback of layer id
TfGrammar(DataBaseType &db, ErrorHandler< Iterator > &error_handler)
constructor
qi::rule< Iterator, Skipper > block_display
technology display