From 1e0b1c8c80d700d27b74d8b8a8d61d56aecc0fef Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 20 Mar 2008 14:42:28 -0700 Subject: [PATCH] crushtool: parses! --- src/crush/grammar.h | 59 ++++++++----------------- src/crush/sample.txt | 8 ++-- src/crushtool.cc | 101 +++++++++++++++++++++++-------------------- 3 files changed, 77 insertions(+), 91 deletions(-) diff --git a/src/crush/grammar.h b/src/crush/grammar.h index 3ec4b30134b35..e87332f9bdd2d 100644 --- a/src/crush/grammar.h +++ b/src/crush/grammar.h @@ -15,17 +15,20 @@ #ifndef __CRUSH_GRAMMAR #define __CRUSH_GRAMMAR +#define BOOST_SPIRIT_DEBUG + +#include +#include +#include using namespace boost::spirit; struct crush_grammar : public 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 template struct definition { - rule, parser_tag > expression; - rule, parser_tag > term; - rule, parser_tag > factor; - rule, parser_tag > integer; - + rule, parser_tag<_int> > integer; rule, parser_tag<_posint> > posint; + rule, parser_tag<_negint> > negint; rule, parser_tag<_name> > name; rule, parser_tag<_device> > device; @@ -78,16 +78,17 @@ struct crush_grammar : public 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 // 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, parser_tag > const& - start() const { return expression; } + rule, parser_tag<_crushmap> > const& + start() const { return crushmap; } }; }; diff --git a/src/crush/sample.txt b/src/crush/sample.txt index d74ec2b8e6fda..1656fe16c45ac 100644 --- a/src/crush/sample.txt +++ b/src/crush/sample.txt @@ -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 diff --git a/src/crushtool.cc b/src/crushtool.cc index 58e936ebd2fe7..ae98536d0fbde 100644 --- a/src/crushtool.cc +++ b/src/crushtool.cc @@ -12,10 +12,6 @@ * */ -#include -#include -#include - #include #include #include @@ -36,15 +32,13 @@ #include using namespace std; - -using namespace boost::spirit; - -typedef char const* iterator_t; +/*typedef char const* iterator_t; typedef tree_match 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 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 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; } -- 2.39.5