IDFstepper
IDF to STEP converter
inc/IdfGrammar.hpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines