]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crushtool: parses!
authorSage Weil <sage@newdream.net>
Thu, 20 Mar 2008 21:42:28 +0000 (14:42 -0700)
committerSage Weil <sage@newdream.net>
Thu, 20 Mar 2008 21:42:28 +0000 (14:42 -0700)
src/crush/grammar.h
src/crush/sample.txt
src/crushtool.cc

index 3ec4b30134b35fd08b750b496620db186d8d0787..e87332f9bdd2db72bfb355338362714eba480bbd 100644 (file)
 #ifndef __CRUSH_GRAMMAR
 #define __CRUSH_GRAMMAR
 
+#define BOOST_SPIRIT_DEBUG
+
+#include <boost/spirit/core.hpp>
+#include <boost/spirit/tree/ast.hpp>
+#include <boost/spirit/tree/tree_to_xml.hpp>
 using namespace boost::spirit;
 
 struct crush_grammar : public grammar<crush_grammar>
 {
-  static const int integerID = 1;
-  static const int factorID = 2;
-  static const int termID = 3;
-  static const int expressionID = 4;
-  
-  static const int _posint = 10;
-  static const int _name = 11;
+  static const int _int = 1;
+  static const int _posint = 2;
+  static const int _negint = 3;
+  static const int _name = 4;
+
   static const int _device = 12;
   static const int _bucket_type = 13;
   static const int _bucket_id = 14;
@@ -45,12 +48,9 @@ struct crush_grammar : public grammar<crush_grammar>
   template <typename ScannerT>
   struct definition
   {
-    rule<ScannerT, parser_context<>, parser_tag<expressionID> >   expression;
-    rule<ScannerT, parser_context<>, parser_tag<termID> >         term;
-    rule<ScannerT, parser_context<>, parser_tag<factorID> >       factor;
-    rule<ScannerT, parser_context<>, parser_tag<integerID> >      integer;
-
+    rule<ScannerT, parser_context<>, parser_tag<_int> >      integer;
     rule<ScannerT, parser_context<>, parser_tag<_posint> >      posint;
+    rule<ScannerT, parser_context<>, parser_tag<_negint> >      negint;
     rule<ScannerT, parser_context<>, parser_tag<_name> >      name;
 
     rule<ScannerT, parser_context<>, parser_tag<_device> >      device;
@@ -78,16 +78,17 @@ struct crush_grammar : public grammar<crush_grammar>
                                            (!ch_p('-') >> +digit_p)
                                            ] ];
       posint     =   leaf_node_d[ lexeme_d[ +digit_p ] ];
-      name = +alnum_p;
+      negint     =   leaf_node_d[ lexeme_d[ ch_p('-') >> +digit_p ] ];
+      name = leaf_node_d[ lexeme_d[ +alnum_p ] ];
 
       // devices
-      device = str_p("device") >> posint >> name >> *(str_p("overload") >> real_p);
+      device = str_p("device") >> posint >> name >> !( str_p("overload") >> real_p );
       
       // bucket types
       bucket_type = str_p("buckettype") >> posint >> name;
 
       // buckets
-      bucket_id = str_p("id") >> ch_p('-') >> posint;
+      bucket_id = str_p("id") >> negint;
       bucket_alg = str_p("alg") >> ( str_p("uniform") | str_p("list") | str_p("tree") | str_p("straw") );
       bucket_item = str_p("item") >> name
                                  >> !( str_p("weight") >> real_p )
@@ -110,34 +111,10 @@ struct crush_grammar : public grammar<crush_grammar>
 
       // the whole crush map
       crushmap = *(device | bucket_type) >> *bucket >> *crushrule;
-       
-
-
-      //  Start grammar definition
-      factor      =   integer
-       |   inner_node_d[ch_p('(') >> expression >> ch_p(')')]
-       |   (root_node_d[ch_p('-')] >> factor);
-      
-      term        =   factor >>
-       *(  (root_node_d[ch_p('*')] >> factor)
-           | (root_node_d[ch_p('/')] >> factor)
-           );
-      
-      expression  =   term >>
-       *(  (root_node_d[ch_p('+')] >> term)
-           | (root_node_d[ch_p('-')] >> term)
-           );
-      //  End grammar definition
-      
-      // turn on the debugging info.
-      BOOST_SPIRIT_DEBUG_RULE(integer);
-      BOOST_SPIRIT_DEBUG_RULE(factor);
-      BOOST_SPIRIT_DEBUG_RULE(term);
-      BOOST_SPIRIT_DEBUG_RULE(expression);
     }
     
-    rule<ScannerT, parser_context<>, parser_tag<expressionID> > const& 
-    start() const { return expression; }
+    rule<ScannerT, parser_context<>, parser_tag<_crushmap> > const& 
+    start() const { return crushmap; }
   };
 };
 
index d74ec2b8e6fda8592775add4952d4ca8523bd8f9..1656fe16c45ac000a875e1fcfb770de76ec760ad 100644 (file)
@@ -3,22 +3,22 @@
 device 1 osd001
 device 2 osd002
 device 3 osd003
-device 4 osd004 overload 0      # 0.0 -> normal, 1.0 -> failed
-device 5 osd005 overload .1
+device 4 osd004 overload 0       # 0.0 -> normal, 1.0 -> failed
+device 5 osd005 overload 0.1
 
 # hierarchy
 buckettype 2 cab
 buckettype 3 row
 buckettype 10 pool
 
-cab cab-d2 {
+cab cabd2 {
        id -1         # optional
        alg straw     # required
        item osd001
        item osd002 weight 600 pos 1
        item osd003 weight 600 pos 2
        item osd004 weight 600 pos 3
-       item osd005 pos 4 weight 600
+       item osd005 weight 600 pos 4
 }
 
 # rules
index 58e936ebd2fe729e095c60b8d41970f1aa050381..ae98536d0fbde629aa747fb61b9f3126de6a253b 100644 (file)
  * 
  */
 
-#include <boost/spirit/core.hpp>
-#include <boost/spirit/tree/ast.hpp>
-#include <boost/spirit/tree/tree_to_xml.hpp>
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <map>
 using namespace std;
 
-
-using namespace boost::spirit;
-
-typedef char const*         iterator_t;
+/*typedef char const*         iterator_t;
 typedef tree_match<iterator_t> parse_tree_match_t;
 typedef parse_tree_match_t::tree_iterator iter_t;
-
+*/
 
 //
+/*
 long evaluate(parse_tree_match_t hit);
 long eval_expression(iter_t const& i);
 
@@ -115,49 +109,64 @@ long eval_expression(iter_t const& i)
   
   return 0;
 }
+*/
+
 
 ////////////////////////////////////////////////////////////////////////////
 int main(int argc, char **argv)
 {
-  // look in tree_calc_grammar for the definition of crush_grammar
-  crush_grammar calc;
-  
-  cout << "/////////////////////////////////////////////////////////\n\n";
-  cout << "\t\tThe simplest working crush_grammar...\n\n";
-  cout << "/////////////////////////////////////////////////////////\n\n";
-  cout << "Type an expression...or [q or Q] to quit\n\n";
   
+  cout << "go" << std::endl;
+  string big;
   string str;
-  while (getline(cin, str))
-    {
-      if (str.empty() || str[0] == 'q' || str[0] == 'Q')
-       break;
-      
-      tree_parse_info<> info = ast_parse(str.c_str(), calc);
-      
-      if (info.full)
-        {
-#if defined(BOOST_SPIRIT_DUMP_PARSETREE_AS_XML)
-         // dump parse tree as XML
-         std::map<parser_id, std::string> rule_names;
-         rule_names[crush_grammar::integerID] = "integer";
-         rule_names[crush_grammar::factorID] = "factor";
-         rule_names[crush_grammar::termID] = "term";
-         rule_names[crush_grammar::expressionID] = "expression";
-         tree_to_xml(cout, info.trees, str.c_str(), rule_names);
-#endif
-         
-         // print the result
-         cout << "parsing succeeded\n";
-         cout << "result = " << evaluate(info) << "\n\n";
-        }
-      else
-        {
-         cout << "parsing failed\n";
-        }
-    }
-  
-  cout << "Bye... :-) \n\n";
+  int line = 1;
+  while (getline(cin, str)) {
+    // fixme: strip out comments
+    int l = str.length();
+    if (l && str[l] == '\n')
+      str.erase(l-1, 1);
+    int n = str.find("#");
+    if (n >= 0)
+      str.erase(n, str.length()-n);
+    cout << line++ << ": " << str << std::endl;
+    if (big.length()) big += " ";
+    big += str;
+  }
+
+  cout << "whole file is: \"" << big << "\"" << std::endl;
+
+  crush_grammar crushg;
+  //bool parsed = parse(big.c_str(), crushg, space_p).full;
+  tree_parse_info<> info = ast_parse(big.c_str(), crushg, space_p);
+  bool parsed = info.full;
+
+  if (parsed) {
+    // dump parse tree as XML
+    std::map<parser_id, std::string> rule_names;
+    rule_names[crush_grammar::_int] = "int";
+    rule_names[crush_grammar::_posint] = "posint";
+    rule_names[crush_grammar::_name] = "name";
+    rule_names[crush_grammar::_device] = "device";
+    rule_names[crush_grammar::_bucket_type] = "bucket_type";
+    rule_names[crush_grammar::_bucket_id] = "bucket_id";
+    rule_names[crush_grammar::_bucket_alg] = "bucket_alg";
+    rule_names[crush_grammar::_bucket_item] = "bucket_item";
+    rule_names[crush_grammar::_bucket] = "bucket";
+    rule_names[crush_grammar::_step_take] = "step_take";
+    rule_names[crush_grammar::_step_choose_indep] = "step_choose_indep";
+    rule_names[crush_grammar::_step_choose_firstn] = "step_choose_firstn";
+    rule_names[crush_grammar::_step_emit] = "step_emit";
+    rule_names[crush_grammar::_crushrule] = "rule";
+    rule_names[crush_grammar::_crushmap] = "map";
+    tree_to_xml(cout, info.trees, big.c_str(), rule_names);
+
+    // print the result
+    cout << "parsing succeeded\n";
+    //cout << "result = " << evaluate(info) << "\n\n";
+  } else {
+    cout << "did not parse" << std::endl;
+  }
+
   return 0;
 }