#pragma once #include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_fusion.hpp> #include <boost/spirit/include/phoenix_stl.hpp> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/variant/recursive_variant.hpp> #include <boost/foreach.hpp> #include "DecayTree/DecayTree.hh" #include <iostream> #include <fstream> #include <string> #include <cstdlib> #include <vector> namespace setupGrammar { namespace fusion = boost::fusion; namespace phoenix = boost::phoenix; namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; /////////////////////////////////////////////////////////////////////////// // Our mini DECAY tree representation /////////////////////////////////////////////////////////////////////////// struct decay_tree; } // We need to tell fusion about our setup struct // to make it a first-class fusion citizen BOOST_FUSION_ADAPT_STRUCT( setupGrammar::decay_tree, (std::string, name) (std::vector<setupGrammar::decay_node>, children) (std::vector<std::string>, addParticle) (std::vector<std::string>, cloneParticle) (std::vector<std::string>, modParticle) (std::vector<std::string>, beamInput) (std::vector<std::string>, mcInput) (std::vector<std::string>, defineTuple) (std::vector<std::string>, fitVars) (std::vector<std::string>, initialProps) ) namespace setupGrammar { /////////////////////////////////////////////////////////////////////////// // Print out the mini decay tree /////////////////////////////////////////////////////////////////////////// int const tabsize = 4; decayGraph::EdgeList edgeList; void tab(int indent) { for (int i = 0; i < indent; ++i) std::cout << ' '; } void vertexToEdgeList(const std::string& name) { edgeList.lastVertexNumber++; edgeList.particleNames.insert(std::pair<int, std::string>(edgeList.lastVertexNumber, name)); if (edgeList.decays.size() > 0) { (*edgeList.lastVertex)->daughters.push_back(edgeList.lastVertexNumber); } edgeList.decays.push_back(new decayGraph::Decay(edgeList.lastVertexNumber)); edgeList.lastVertex = edgeList.decays.rbegin(); } void finalToEdgeList(const std::string& name) { edgeList.lastVertexNumber++; edgeList.particleNames.insert(std::pair<int, std::string>(edgeList.lastVertexNumber, name)); (*edgeList.lastVertex)->daughters.push_back(edgeList.lastVertexNumber); while(edgeList.lastVertex != edgeList.decays.rend() && (*edgeList.lastVertex)->daughters.size() == 2 ) edgeList.lastVertex++; } struct decay_tree_printer { decay_tree_printer(int indent = 0) : indent(indent) { } void operator()(decay_tree const& decay) const; int indent; }; struct decay_node_printer : boost::static_visitor<> { decay_node_printer(int indent = 0) : indent(indent) {} void operator()(decay_tree const& decay) const { decay_tree_printer(indent+tabsize)(decay); } void operator()(std::string const& text) const { tab(indent+tabsize); std::cout << "final state particle " << text << std::endl; finalToEdgeList(text); } int indent; }; void decay_tree_printer::operator()(decay_tree const& decay) const { tab(indent); std::cout << decay.name << " -> " << std::endl; vertexToEdgeList(decay.name); BOOST_FOREACH(decay_node const& node, decay.children) { boost::apply_visitor(decay_node_printer(indent), node); } tab(indent); std::vector<std::string>::const_iterator iter; iter = decay.addParticle.begin(); while (iter != decay.addParticle.end()) { std::cout << "new particle: " << *iter << std::endl; ++iter; } iter = decay.cloneParticle.begin(); while (iter != decay.cloneParticle.end()) { std::cout << "cloned particle: " << *iter << std::endl; ++iter; } iter = decay.modParticle.begin(); while (iter != decay.modParticle.end()) { std::cout << "modified particle: " << *iter << std::endl; ++iter; } std::cout << std::endl; } /////////////////////////////////////////////////////////////////////////// // Our mini DECAY grammar definition /////////////////////////////////////////////////////////////////////////// //[tutorial_decay1_grammar template <typename Iterator> struct setup_file_grammar : qi::grammar<Iterator, decay_tree(), ascii::space_type> { setup_file_grammar() : setup_file_grammar::base_type(decay) { using qi::lit; using qi::lexeme; using ascii::char_; using ascii::string; using namespace qi::labels; using phoenix::at_c; using phoenix::push_back; using boost::phoenix::ref; restOfLine = lexeme[*(char_ -'\n') [_val += _1]]; comment = (char_('#') >> lexeme[*(char_ -'\n')]); particleName = lexeme[+(char_('!','z') -',') [_val += _1]]; decNode = (decay | particleName); goesTo = char_('-') >> char_('>'); decay = +( comment || "addParticle" >> restOfLine[push_back(at_c<2>(_val), _1)] || "cloneParticle" >> restOfLine[push_back(at_c<3>(_val), _1)] || "modParticle" >> restOfLine[push_back(at_c<4>(_val), _1)] || "beamInput" >> restOfLine[push_back(at_c<5>(_val), _1)] || "mcInput" >> restOfLine[push_back(at_c<6>(_val), _1)] || "defineTuple" >> restOfLine[push_back(at_c<7>(_val), _1)] || "fitVariables" >> restOfLine[push_back(at_c<8>(_val), _1)] || "initialProperties" >> restOfLine[push_back(at_c<9>(_val), _1)] || ( char_('{') >> (decay[push_back(at_c<1>(_val), _1)] || particleName[at_c<0>(_val) = _1]) >> goesTo >> decNode [push_back(at_c<1>(_val), _1)] >> ',' >> decNode [push_back(at_c<1>(_val), _1)] >> char_('}') ) ); } qi::rule<Iterator, decay_tree(), ascii::space_type> decay; qi::rule<Iterator, decay_node(), ascii::space_type> decNode; qi::rule<Iterator, std::string(), ascii::space_type> goesTo; qi::rule<Iterator, std::string(), ascii::space_type> comment; qi::rule<Iterator, std::string(), ascii::space_type> restOfLine; qi::rule<Iterator, std::string(), ascii::space_type> particleName; }; }