• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

grammar.h

Go to the documentation of this file.
00001 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
00002 // vim: ts=8 sw=2 smarttab
00003 /*
00004  * Ceph - scalable distributed file system
00005  *
00006  * Copyright (C) 2004-2008 Sage Weil <sage@newdream.net>
00007  *
00008  * This is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License version 2.1, as published by the Free Software
00011  * Foundation.  See file COPYING.
00012  *
00013  */
00014 
00015 #ifndef __CRUSH_GRAMMAR_H
00016 #define __CRUSH_GRAMMAR_H
00017 
00018 //#define BOOST_SPIRIT_DEBUG
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& /*self*/)
00076     {
00077       // base types
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       // devices
00086       device = str_p("device") >> posint >> name;
00087 
00088       // bucket types
00089       bucket_type = str_p("type") >> posint >> name;
00090 
00091       // buckets
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       // rules
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       // the whole crush map
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

Generated on Mon Oct 11 2010 13:09:26 for CppDistributors by  doxygen 1.7.2