00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __CRUSH_GRAMMAR_H
00016 #define __CRUSH_GRAMMAR_H
00017
00018
00019
00020 #include <boost/spirit/core.hpp>
00021 #include <boost/spirit/tree/ast.hpp>
00022 #include <boost/spirit/tree/tree_to_xml.hpp>
00023 using namespace boost::spirit;
00024
00025 struct crush_grammar : public grammar<crush_grammar>
00026 {
00027 enum {
00028 _int = 1,
00029 _posint,
00030 _negint,
00031 _name,
00032 _device,
00033 _bucket_type,
00034 _bucket_id,
00035 _bucket_alg,
00036 _bucket_hash,
00037 _bucket_item,
00038 _bucket,
00039 _step_take,
00040 _step_choose,
00041 _step_chooseleaf,
00042 _step_emit,
00043 _step,
00044 _crushrule,
00045 _crushmap,
00046 };
00047
00048 template <typename ScannerT>
00049 struct definition
00050 {
00051 rule<ScannerT, parser_context<>, parser_tag<_int> > integer;
00052 rule<ScannerT, parser_context<>, parser_tag<_posint> > posint;
00053 rule<ScannerT, parser_context<>, parser_tag<_negint> > negint;
00054 rule<ScannerT, parser_context<>, parser_tag<_name> > name;
00055
00056 rule<ScannerT, parser_context<>, parser_tag<_device> > device;
00057
00058 rule<ScannerT, parser_context<>, parser_tag<_bucket_type> > bucket_type;
00059
00060 rule<ScannerT, parser_context<>, parser_tag<_bucket_id> > bucket_id;
00061 rule<ScannerT, parser_context<>, parser_tag<_bucket_alg> > bucket_alg;
00062 rule<ScannerT, parser_context<>, parser_tag<_bucket_hash> > bucket_hash;
00063 rule<ScannerT, parser_context<>, parser_tag<_bucket_item> > bucket_item;
00064 rule<ScannerT, parser_context<>, parser_tag<_bucket> > bucket;
00065
00066 rule<ScannerT, parser_context<>, parser_tag<_step_take> > step_take;
00067 rule<ScannerT, parser_context<>, parser_tag<_step_choose> > step_choose;
00068 rule<ScannerT, parser_context<>, parser_tag<_step_chooseleaf> > step_chooseleaf;
00069 rule<ScannerT, parser_context<>, parser_tag<_step_emit> > step_emit;
00070 rule<ScannerT, parser_context<>, parser_tag<_step> > step;
00071 rule<ScannerT, parser_context<>, parser_tag<_crushrule> > crushrule;
00072
00073 rule<ScannerT, parser_context<>, parser_tag<_crushmap> > crushmap;
00074
00075 definition(crush_grammar const& )
00076 {
00077
00078 integer = leaf_node_d[ lexeme_d[
00079 (!ch_p('-') >> +digit_p)
00080 ] ];
00081 posint = leaf_node_d[ lexeme_d[ +digit_p ] ];
00082 negint = leaf_node_d[ lexeme_d[ ch_p('-') >> +digit_p ] ];
00083 name = leaf_node_d[ lexeme_d[ +alnum_p ] ];
00084
00085
00086 device = str_p("device") >> posint >> name;
00087
00088
00089 bucket_type = str_p("type") >> posint >> name;
00090
00091
00092 bucket_id = str_p("id") >> negint;
00093 bucket_alg = str_p("alg") >> ( str_p("uniform") |
00094 str_p("list") |
00095 str_p("tree") |
00096 str_p("straw") );
00097 bucket_hash = str_p("hash") >> ( integer |
00098 str_p("rjenkins1") );
00099 bucket_item = str_p("item") >> name
00100 >> !( str_p("weight") >> real_p )
00101 >> !( str_p("pos") >> posint );
00102 bucket = name >> name >> '{' >> !bucket_id >> bucket_alg >> *bucket_hash >> *bucket_item >> '}';
00103
00104
00105 step_take = str_p("take") >> name;
00106 step_choose = str_p("choose")
00107 >> ( str_p("indep") | str_p("firstn") )
00108 >> integer
00109 >> str_p("type") >> name;
00110 step_chooseleaf = str_p("chooseleaf")
00111 >> ( str_p("indep") | str_p("firstn") )
00112 >> integer
00113 >> str_p("type") >> name;
00114 step_emit = str_p("emit");
00115 step = str_p("step") >> ( step_take |
00116 step_choose |
00117 step_chooseleaf |
00118 step_emit );
00119 crushrule = str_p("rule") >> !name >> '{'
00120 >> str_p("ruleset") >> posint
00121 >> str_p("type") >> ( str_p("replicated") | str_p("raid4") )
00122 >> str_p("min_size") >> posint
00123 >> str_p("max_size") >> posint
00124 >> +step
00125 >> '}';
00126
00127
00128 crushmap = *(device | bucket_type) >> *bucket >> *crushrule;
00129 }
00130
00131 rule<ScannerT, parser_context<>, parser_tag<_crushmap> > const&
00132 start() const { return crushmap; }
00133 };
00134 };
00135
00136 #endif