IDFstepper
IDF to STEP converter
|
00001 #ifndef IDFGRAMMAR_HPP_INCLUDED 00002 #define IDFGRAMMAR_HPP_INCLUDED 00003 00006 #define FUSION_MAX_VECTOR_SIZE 20 00007 00008 #include "IdfStructure.hpp" 00009 00010 #include <boost/optional.hpp> 00011 #include <boost/config/warning_disable.hpp> 00012 #include <boost/spirit/include/qi.hpp> 00013 #include <boost/spirit/include/phoenix_core.hpp> 00014 #include <boost/spirit/include/phoenix_operator.hpp> 00015 #include <boost/spirit/include/phoenix_fusion.hpp> 00016 #include <boost/spirit/include/phoenix_stl.hpp> 00017 #include <boost/spirit/include/phoenix_object.hpp> 00018 #include <boost/fusion/include/adapt_struct.hpp> 00019 #include <boost/variant/recursive_variant.hpp> 00020 #include <boost/foreach.hpp> 00021 00022 #include <iostream> 00023 #include <fstream> 00024 #include <string> 00025 #include <vector> 00026 #include <map> 00027 00035 // Adapt structures to Boost::Fusion 00036 BOOST_FUSION_ADAPT_STRUCT( 00037 idf::Loop, 00038 (int, label) 00039 (double, x) 00040 (double, y) 00041 (double, angle) 00042 ) 00043 00044 BOOST_FUSION_ADAPT_STRUCT( 00045 idf::BoardPanelOutline, 00046 (idf::Owner, owner) 00047 (double, thickness) 00048 (std::vector<idf::Loop>, loops) 00049 ) 00050 00051 BOOST_FUSION_ADAPT_STRUCT( 00052 idf::OtherOutline, 00053 (idf::Owner, owner) 00054 (std::string, identifier) 00055 (double, thickness) 00056 (idf::BoardSide, side) 00057 (std::vector<idf::Loop>, loops) 00058 ) 00059 00060 BOOST_FUSION_ADAPT_STRUCT( 00061 idf::RoutingOutline, 00062 (idf::Owner, owner) 00063 (idf::RoutingLayers, layers) 00064 (std::vector<idf::Loop>, loops) 00065 ) 00066 00067 BOOST_FUSION_ADAPT_STRUCT( 00068 idf::PlacementOutline, 00069 (idf::Owner, owner) 00070 (idf::BoardSide, side) 00071 (double, height) 00072 (std::vector<idf::Loop>, loops) 00073 ) 00074 00075 BOOST_FUSION_ADAPT_STRUCT( 00076 idf::RoutingKeepout, 00077 (idf::Owner, owner) 00078 (idf::RoutingLayers, layers) 00079 (std::vector<idf::Loop>, loops) 00080 ) 00081 00082 BOOST_FUSION_ADAPT_STRUCT( 00083 idf::ViaKeepout, 00084 (idf::Owner, owner) 00085 (std::vector<idf::Loop>, loops) 00086 ) 00087 00088 BOOST_FUSION_ADAPT_STRUCT( 00089 idf::PlacementKeepout, 00090 (idf::Owner, owner) 00091 (idf::BoardSide, side) 00092 (double, height) 00093 (std::vector<idf::Loop>, loops) 00094 ) 00095 00096 BOOST_FUSION_ADAPT_STRUCT( 00097 idf::PlacementGroupArea, 00098 (idf::Owner, owner) 00099 (idf::BoardSide, side) 00100 (std::string, name) 00101 (std::vector<idf::Loop>, loops) 00102 ) 00103 00104 BOOST_FUSION_ADAPT_STRUCT( 00105 idf::DrilledHole, 00106 (double, diameter) 00107 (double, x) 00108 (double, y) 00109 (idf::PlatingStyle, style) 00110 (std::string, associatedPart) 00111 (std::string, type) 00112 (idf::Owner, owner) 00113 ) 00114 00115 BOOST_FUSION_ADAPT_STRUCT( 00116 idf::DrilledHoles, 00117 (std::vector<idf::DrilledHole>, holes) 00118 ) 00119 00120 BOOST_FUSION_ADAPT_STRUCT( 00121 idf::Note, 00122 (double, x) 00123 (double, y) 00124 (double, height) 00125 (double, length) 00126 (std::string, text) 00127 ) 00128 00129 BOOST_FUSION_ADAPT_STRUCT( 00130 idf::Notes, 00131 (std::vector<idf::Note>, notes) 00132 ) 00133 00134 BOOST_FUSION_ADAPT_STRUCT( 00135 idf::ComponentPlacement, 00136 (std::string, package) 00137 (std::string, number) 00138 (std::string, refdes) 00139 (double, x) 00140 (double, y) 00141 (double, offset) 00142 (double, angle) 00143 (idf::BoardSide, side) 00144 (idf::PlacementStatus, status) 00145 ) 00146 00147 BOOST_FUSION_ADAPT_STRUCT( 00148 idf::ComponentPlacements, 00149 (std::vector<idf::ComponentPlacement>, placements) 00150 ) 00151 00152 BOOST_FUSION_ADAPT_STRUCT( 00153 idf::BoardPanelStruct, 00154 (idf::BoardPanelType, fileType) 00155 (double, idfVersion) 00156 (std::string, sourceSysId) 00157 (std::string, date) 00158 (int, version) 00159 (std::string, name) 00160 (idf::Unit, units) 00161 (idf::BoardPanelOutline, outline) 00162 (std::vector<idf::OtherOutline>, otherOutlines) 00163 (std::vector<idf::RoutingOutline>, routingOutlines) 00164 (std::vector<idf::PlacementOutline>, placementOutlines) 00165 (std::vector<idf::RoutingKeepout>, routingKeepouts) 00166 (std::vector<idf::ViaKeepout>, viaKeepouts) 00167 (std::vector<idf::PlacementKeepout>, placementKeepouts) 00168 (std::vector<idf::PlacementGroupArea>, placementGroups) 00169 (boost::optional<idf::DrilledHoles>, holes) 00170 (boost::optional<idf::Notes>, notes) 00171 (boost::optional<idf::ComponentPlacements>, components) 00172 ) 00173 00174 BOOST_FUSION_ADAPT_STRUCT( 00175 idf::Component, 00176 (idf::ComponentType, type) 00177 (std::string, name) 00178 (std::string, number) 00179 (idf::Unit, units) 00180 (double, height) 00181 (std::vector<idf::Loop>, loops) 00182 (boost::optional<idf::Props>, props) 00183 ); 00184 00185 BOOST_FUSION_ADAPT_STRUCT( 00186 idf::LibraryStruct, 00187 (double, idfVersion) 00188 (std::string, sourceSysId) 00189 (std::string, date) 00190 (int, version) 00191 (std::vector<idf::Component>, components) 00192 ); 00193 00194 namespace idf { 00195 00196 namespace fusion = boost::fusion; 00197 namespace phoenix = boost::phoenix; 00198 namespace qi = boost::spirit::qi; 00199 namespace ascii = boost::spirit::ascii; 00200 00207 template <typename Iterator> 00208 struct BoardPanelGrammar 00209 : qi::grammar<Iterator, BoardPanelStruct(), qi::rule<Iterator> > 00210 { 00211 00212 typedef qi::rule<Iterator> SkipType; 00213 00214 BoardPanelGrammar() : BoardPanelGrammar::base_type(boardPanelStruct) { 00215 using qi::lit; 00216 using qi::eol; 00217 using qi::lexeme; 00218 using qi::double_; 00219 using qi::int_; 00220 using qi::debug; 00221 using qi::eps; 00222 using ascii::blank; 00223 using ascii::char_; 00224 using ascii::string; 00225 using ascii::no_case; 00226 using namespace qi::labels; 00227 00228 skipper = blank; // Tabs and spaces 00229 00230 eeol = +(eol | (lit('#') >> *(char_ - eol) >> eol)); 00231 00232 quotedStr %= '"' >> *(char_ - '"') >> '"'; 00233 00234 str %= quotedStr | +(char_ - blank - eeol); 00235 00236 boardPanelType = 00237 no_case["board_file"] [_val = BOARD_FILE] 00238 | no_case["panel_file"] [_val = PANEL_FILE]; 00239 00240 unit = -lit('"') >> ( 00241 no_case[lit("mm") [_val = MM]] 00242 | no_case[lit("thou") [_val = THOU]] 00243 ) >> -lit('"'); 00244 00245 owner = -lit('"') >> ( 00246 no_case[lit("mcad") [_val = MCAD]] 00247 | no_case[lit("ecad") [_val = ECAD]] 00248 | no_case[lit("unowned") [_val = UNOWNED]] 00249 ) >> -lit('"'); 00250 00251 boardSide = -lit('"') >> ( 00252 no_case[lit("top") [_val = TOP_SIDE]] 00253 | no_case[lit("bottom") [_val = BOTTOM_SIDE]] 00254 | no_case[lit("both") [_val = BOTH_SIDES]] 00255 ) >> -lit('"'); 00256 00257 routingLayers = -lit('"') >> ( 00258 no_case[lit("top") [_val = TOP_LAYER]] 00259 | no_case[lit("bottom") [_val = BOTTOM_LAYER]] 00260 | no_case[lit("both") [_val = BOTH_LAYERS]] 00261 | no_case[lit("inner") [_val = INNER_LAYERS]] 00262 | no_case[lit("all") [_val = ALL_LAYERS]] 00263 ) >> -lit('"'); 00264 00265 platingStyle = -lit('"') >> ( 00266 no_case[lit("pth") [_val = PTH]] 00267 | no_case[lit("npth") [_val = NPTH]] 00268 ) >> -lit('"'); 00269 00270 placementStatus = -lit('"') >> ( 00271 no_case[lit("placed") [_val = PLACED]] 00272 | no_case[lit("unplaced") [_val = UNPLACED]] 00273 | no_case[lit("mcad") [_val = PLACE_MCAD]] 00274 | no_case[lit("ecad") [_val = PLACE_ECAD]] 00275 ) >> -lit('"'); 00276 00277 // Needed because the field is optional, default to 0.0 if missing 00278 outlineHeight = 00279 double_ [_val = _1] 00280 | eps [_val = 0.0]; 00281 00282 loop %= int_ >> double_ >> double_ >> double_ >> eeol; 00283 00284 boardPanelOutline %= 00285 no_case[lit(".board_outline") | ".panel_outline"] 00286 >> owner >> eeol 00287 >> double_ >> eeol 00288 >> +loop 00289 >> no_case[lit(".end_board_outline") | lit(".end_panel_outline")] 00290 >> eeol; 00291 00292 otherOutline %= 00293 no_case[".other_outline"] 00294 >> owner >> eeol 00295 >> str 00296 >> double_ 00297 >> boardSide >> eeol 00298 >> *loop 00299 >> no_case[".end_other_outline"] >> eeol; 00300 00301 routingOutline %= 00302 no_case[".route_outline"] 00303 >> owner >> eeol 00304 >> routingLayers >> eeol 00305 >> *loop 00306 >> no_case[".end_route_outline"] >> eeol; 00307 00308 placementOutline %= 00309 no_case[".place_outline"] 00310 >> owner >> eeol 00311 >> boardSide 00312 >> outlineHeight >> eeol 00313 >> *loop 00314 >> no_case[".end_place_outline"] >> eeol; 00315 00316 routingKeepout %= 00317 no_case[".route_keepout"] 00318 >> owner >> eeol 00319 >> routingLayers >> eeol 00320 >> *loop 00321 >> no_case[".end_route_keepout"] >> eeol; 00322 00323 viaKeepout %= 00324 no_case[".via_keepout"] 00325 >> owner >> eeol 00326 >> *loop 00327 >> no_case[".end_via_keepout"] >> eeol; 00328 00329 placementKeepout %= 00330 no_case[".place_keepout"] 00331 >> owner >> eeol 00332 >> boardSide 00333 >> double_ >> eeol 00334 >> *loop 00335 >> no_case[".end_place_keepout"] >> eeol; 00336 00337 placementGroupArea %= 00338 no_case[".place_region"] 00339 >> owner >> eeol 00340 >> boardSide 00341 >> str >> eeol 00342 >> *loop 00343 >> no_case[".end_place_region"] >> eeol; 00344 00345 drilledHole %= 00346 double_ 00347 >> double_ 00348 >> double_ 00349 >> platingStyle 00350 >> str 00351 >> str 00352 >> owner 00353 >> eeol; 00354 00355 drilledHoles %= 00356 no_case[".drilled_holes"] >> eeol 00357 >> *drilledHole 00358 >> no_case[".end_drilled_holes"] >> eeol; 00359 00360 note %= 00361 double_ 00362 >> double_ 00363 >> double_ 00364 >> double_ 00365 >> str 00366 >> eeol; 00367 00368 notes %= 00369 no_case[".notes"] >> eeol 00370 >> *note 00371 >> no_case[".end_notes"] >> eeol; 00372 00373 componentPlacement %= 00374 str 00375 >> str 00376 >> str 00377 >> eeol 00378 >> double_ 00379 >> double_ 00380 >> double_ 00381 >> double_ 00382 >> boardSide 00383 >> placementStatus 00384 >> eeol; 00385 00386 componentPlacements %= 00387 no_case[".placement"] >> eeol 00388 >> *componentPlacement 00389 >> no_case[".end_placement"] >> *eeol; 00390 00391 boardPanelStruct %= 00392 *eeol 00393 >> no_case[".header"] >> eeol 00394 >> boardPanelType 00395 >> double_ 00396 >> str 00397 >> str 00398 >> int_ >> eeol 00399 >> str 00400 >> unit >> eeol 00401 >> no_case[".end_header"] >> eeol 00402 >> boardPanelOutline 00403 >> *otherOutline 00404 >> *routingOutline 00405 >> *placementOutline 00406 >> *routingKeepout 00407 >> *viaKeepout 00408 >> *placementKeepout 00409 >> *placementGroupArea 00410 >> -drilledHoles 00411 >> -notes 00412 >> -componentPlacements; 00413 00414 quotedStr.name("quoted string"); 00415 str.name("string"); 00416 boardPanelType.name("boardPanelType"); 00417 unit.name("unit"); 00418 owner.name("owner"); 00419 boardSide.name("boardSide"); 00420 routingLayers.name("routingLayers"); 00421 platingStyle.name("platingStyle"); 00422 placementStatus.name("placementStatus"); 00423 outlineHeight.name("outlineHeight"); 00424 loop.name("loop"); 00425 boardPanelOutline.name("boardPanelOutline"); 00426 otherOutline.name("otherOutline"); 00427 routingOutline.name("routingOutline"); 00428 placementOutline.name("placementOutline"); 00429 routingKeepout.name("routingKeepout"); 00430 viaKeepout.name("viaKeepout"); 00431 placementKeepout.name("placementKeepout"); 00432 placementGroupArea.name("placementGroupArea"); 00433 drilledHole.name("drilledHole"); 00434 drilledHoles.name("drilledHoles"); 00435 note.name("note"); 00436 notes.name("notes"); 00437 componentPlacement.name("componentPlacement"); 00438 componentPlacements.name("componentPlacements"); 00439 boardPanelStruct.name("boardPanelStruct"); 00440 00441 /*debug(quotedStr); 00442 debug(str); 00443 debug(boardPanelType); 00444 debug(unit); 00445 debug(owner); 00446 debug(boardSide); 00447 debug(routingLayers); 00448 debug(platingStyle); 00449 debug(placementStatus); 00450 debug(outlineHeight); 00451 debug(loop); 00452 debug(boardPanelOutline); 00453 debug(otherOutline); 00454 debug(routingOutline); 00455 debug(placementOutline); 00456 debug(routingKeepout); 00457 debug(viaKeepout); 00458 debug(placementKeepout); 00459 debug(placementGroupArea); 00460 debug(drilledHole); 00461 debug(drilledHoles); 00462 debug(note); 00463 debug(notes); 00464 debug(componentPlacement); 00465 debug(componentPlacements); 00466 debug(boardPanelStruct);*/ 00467 } 00468 00471 SkipType skipper; 00472 qi::rule<Iterator> eeol; // Extended EOL for empty lines and comments 00473 00474 qi::rule<Iterator, std::string()> quotedStr; 00475 qi::rule<Iterator, std::string()> str; 00476 qi::rule<Iterator, BoardPanelType()> boardPanelType; 00477 qi::rule<Iterator, Unit()> unit; 00478 qi::rule<Iterator, Owner()> owner; 00479 qi::rule<Iterator, BoardSide()> boardSide; 00480 qi::rule<Iterator, RoutingLayers()> routingLayers; 00481 qi::rule<Iterator, PlatingStyle()> platingStyle; 00482 qi::rule<Iterator, PlacementStatus()> placementStatus; 00483 qi::rule<Iterator, double()> outlineHeight; 00484 qi::rule<Iterator, Loop(), SkipType> loop; 00485 qi::rule<Iterator, BoardPanelOutline(), SkipType> boardPanelOutline; 00486 qi::rule<Iterator, OtherOutline(), SkipType> otherOutline; 00487 qi::rule<Iterator, RoutingOutline(), SkipType> routingOutline; 00488 qi::rule<Iterator, PlacementOutline(), SkipType> placementOutline; 00489 qi::rule<Iterator, RoutingKeepout(), SkipType> routingKeepout; 00490 qi::rule<Iterator, ViaKeepout(), SkipType> viaKeepout; 00491 qi::rule<Iterator, PlacementKeepout(), SkipType> placementKeepout; 00492 qi::rule<Iterator, PlacementGroupArea(), SkipType> placementGroupArea; 00493 qi::rule<Iterator, DrilledHole(), SkipType> drilledHole; 00494 qi::rule<Iterator, DrilledHoles(), SkipType> drilledHoles; 00495 qi::rule<Iterator, Note(), SkipType> note; 00496 qi::rule<Iterator, Notes(), SkipType> notes; 00497 qi::rule<Iterator, ComponentPlacement(), SkipType> componentPlacement; 00498 qi::rule<Iterator, ComponentPlacements(), SkipType> componentPlacements; 00499 qi::rule<Iterator, BoardPanelStruct(), SkipType> boardPanelStruct; 00500 }; 00501 00508 template <typename Iterator> 00509 struct LibraryGrammar 00510 : qi::grammar<Iterator, LibraryStruct(), qi::rule<Iterator> > 00511 { 00512 00513 typedef qi::rule<Iterator> SkipType; 00514 00515 LibraryGrammar() : LibraryGrammar::base_type(libraryStruct) { 00516 using qi::lit; 00517 using qi::eol; 00518 using qi::lexeme; 00519 using qi::double_; 00520 using qi::int_; 00521 using qi::debug; 00522 using qi::eps; 00523 using ascii::blank; 00524 using ascii::char_; 00525 using ascii::string; 00526 using ascii::no_case; 00527 using namespace qi::labels; 00528 00529 skipper = blank; // Tabs and spaces 00530 00531 eeol = +(eol | (lit('#') >> *(char_ - eol) >> eol)); 00532 00533 quotedStr %= '"' >> *(char_ - '"') >> '"'; 00534 00535 str %= quotedStr | +(char_ - blank - eol); 00536 00537 unit = -lit('"') >> ( 00538 no_case[lit("mm") [_val = MM]] 00539 | no_case[lit("thou") [_val = THOU]] 00540 ) >> -lit('"'); 00541 00542 componentType = 00543 no_case[lit(".electrical") [_val = ELECTRICAL]] 00544 | no_case[lit(".mechanical") [_val = MECHANICAL]]; 00545 00546 loop %= int_ >> double_ >> double_ >> double_ >> eeol; 00547 00548 prop %= 00549 no_case["prop"] 00550 >> str 00551 >> -str 00552 >> eeol; 00553 00554 props %= +prop; 00555 00556 component %= 00557 componentType >> eeol 00558 >> str 00559 >> str 00560 >> unit 00561 >> double_ >> eeol 00562 >> *loop 00563 >> -props 00564 >> no_case[lit(".end_electrical") | lit(".end_mechanical")] >> *eeol; 00565 00566 libraryStruct %= 00567 *eeol 00568 >> no_case[".header"] >> eeol 00569 >> no_case["library_file"] 00570 >> double_ 00571 >> str 00572 >> str 00573 >> int_ >> eeol 00574 >> no_case[".end_header"] >> eeol 00575 >> *component; 00576 00577 quotedStr.name("quoted string"); 00578 str.name("string"); 00579 unit.name("unit"); 00580 componentType.name("componentType"); 00581 loop.name("loop"); 00582 prop.name("prop"); 00583 props.name("props"); 00584 component.name("component"); 00585 libraryStruct.name("libraryStruct"); 00586 00587 /*debug(quotedStr); 00588 debug(str); 00589 debug(unit); 00590 debug(componentType); 00591 debug(loop); 00592 //debug(prop); 00593 //debug(props); 00594 //debug(component); 00595 //debug(libraryStruct);*/ 00596 } 00597 00600 SkipType skipper; 00601 qi::rule<Iterator> eeol; // Extended EOL for empty lines and comments 00602 00603 qi::rule<Iterator, std::string()> quotedStr; 00604 qi::rule<Iterator, std::string()> str; 00605 qi::rule<Iterator, Unit()> unit; 00606 qi::rule<Iterator, ComponentType()> componentType; 00607 qi::rule<Iterator, Loop(), SkipType> loop; 00608 qi::rule<Iterator, std::pair<std::string, std::string>, SkipType> prop; 00609 qi::rule<Iterator, Props(), SkipType> props; 00610 qi::rule<Iterator, Component(), SkipType> component; 00611 qi::rule<Iterator, LibraryStruct(), SkipType> libraryStruct; 00612 00613 }; 00614 00615 } 00616 00617 #endif 00618