sehe

parsing for http://stackoverflow.com/questions/8234202/funct

Nov 22nd, 2011
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.70 KB | None | 0 0
  1. #define BOOST_SPIRIT_DEBUG
  2. #include <boost/spirit/include/qi.hpp>
  3. #include <boost/spirit/include/phoenix.hpp>
  4. #include <set>
  5.  
  6. namespace qi=boost::spirit::qi;
  7. namespace phx=boost::phoenix;
  8.  
  9. typedef boost::optional<boost::variant<std::string, double, int> > variant_t;
  10.  
  11. struct object
  12. {
  13.     std::string name;
  14.     // non-key:
  15.     mutable variant_t value;
  16.     mutable std::set<object> children;
  17.  
  18.     object(const std::string& aname) : name(aname) { }
  19.  
  20.     bool operator<(const object& other) const
  21.         { return name < other.name; }
  22.     friend std::ostream& operator<<(std::ostream& os, const object& obj)
  23.         { return obj.dump(os); }
  24.  
  25.   private:
  26.  
  27.     std::ostream& dump(std::ostream& os, std::string indent = "") const
  28.     {
  29.         const std::string extra = "    ";
  30.  
  31.         os << "\n" << indent << "name: " << name;
  32.         if (value) os << " (value: " << *value << ")";
  33.  
  34.         os << "\n" << indent << "{";
  35.         for (auto& o: children) o.dump(os, indent + extra);
  36.         os << "\n" << indent << "}";
  37.  
  38.         return os;
  39.     }
  40. };
  41.  
  42. namespace state // TODO make non-static for reentrance
  43. {
  44.     object globals("<globals>");
  45.     const object* current = &globals;
  46.  
  47.     static void reset()            
  48.         { current = &globals; }
  49.     static void setvalue(variant_t value)
  50.         { current->value = value; }
  51.     static void lookup(const std::string& name)
  52.         { current = &*(current->children.insert(object(name)).first); }
  53. }
  54.  
  55. struct grammar : qi::grammar<std::string::iterator, qi::space_type>
  56. {
  57.     grammar() : grammar::base_type(rule)
  58.     {
  59.         using namespace state;
  60.         using namespace qi;
  61.         using phx::bind;
  62.  
  63.         qual  = as_string [ lexeme [ +(~char_(".") - space) ] ] [ bind(lookup, _1) ];
  64.         name  = eps [ reset ] >> (qual % '.');
  65.         value = (as_string ['"' > *~char_('"') > '"'] | double_ | int_) [ setvalue ];
  66.         rule  = -("Set" >> (name >> value));
  67.  
  68.         BOOST_SPIRIT_DEBUG_NODE(qual);
  69.         BOOST_SPIRIT_DEBUG_NODE(rule);
  70.         BOOST_SPIRIT_DEBUG_NODE(name);
  71.         BOOST_SPIRIT_DEBUG_NODE(value);
  72.     }
  73.  
  74.   private:
  75.  
  76.     qi::rule<std::string::iterator, qi::space_type> qual;
  77.     qi::rule<std::string::iterator, std::string(), qi::space_type> name;
  78.     qi::rule<std::string::iterator, variant_t(), qi::space_type> value;
  79.     qi::rule<std::string::iterator, qi::space_type> rule;
  80. };
  81.  
  82. int main()
  83. {
  84.     std::string input;
  85.     while (std::getline(std::cin, input))
  86.     {
  87.         auto f(input.begin()), l(input.end());
  88.  
  89.         if (!qi::phrase_parse(f,l,grammar(),qi::space))
  90.             std::cout << "failed line '" << input << "'" << std::endl;
  91.     }
  92.  
  93.     std::cout << state::globals << std::endl;
  94. }
  95.  
  96.  
  97.  
Add Comment
Please, Sign In to add comment