Newer
Older
#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 <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
{
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(
(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)
)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
///////////////////////////////////////////////////////////////////////////
// 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;
}
///////////////////////////////////////////////////////////////////////////
// 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_('>');
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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;