tree.cc

Go to the documentation of this file.
00001 #include "tree.h"
00002 #include <boost/spirit/core.hpp>
00003 
00004 namespace {
00005   using namespace boost::spirit;
00006   using std::string;
00007   using namespace opencog;
00008 
00009   tree<string> tr;
00010   tree<string>::iterator at=tr.begin();
00011 
00012   void begin_internal(const char* from, const char* to) {
00013     at= tr.empty() 
00014       ? tr.insert(at,string(from,to-1))
00015       : tr.append_child(at,string(from,to-1));
00016   }
00017   void end_internal(const char) {
00018     at=tr.parent(at);
00019   }
00020   void add_leaf(const char* from, const char* to) {
00021     if (tr.empty())
00022       at=tr.insert(at,string(from,to));
00023     else
00024       tr.append_child(at,string(from,to));
00025   }
00026 
00027   struct TreeGrammar : public grammar<TreeGrammar> {
00028     std::vector<string> v;
00029     
00030     template<typename ScannerT>
00031     struct definition {
00032       definition(const TreeGrammar&) {
00033     term= 
00034       lexeme_d[//or a message M with the syntax message:"M"
00035            //added this to parse correctly has_said perceptions
00036            ( str_p("message:") >> ch_p('"') 
00037                >> *(anychar_p - ch_p('"')) >> ch_p('"'))
00038            | (+( anychar_p - ch_p('(') - ch_p(')') - space_p))]
00039       [&add_leaf];
00040     beg=
00041       lexeme_d[(+( anychar_p - ch_p('(') - ch_p(')') - space_p)) >> '('];
00042     expr=
00043       (beg[&begin_internal] >> +expr >> ch_p(')')[&end_internal]) |
00044       term;
00045     //expr=term | (term >> '(' >> +expr >> ')');
00046       }
00047       rule<ScannerT> expr,beg,term;
00048       
00049       const rule<ScannerT>& start() const { return expr; }
00050     };
00051   };
00052 
00053   tree<std::string> parse_string_tree(const std::string& str) {
00054     TreeGrammar tg;
00055     tr.clear();
00056     at=tr.begin();
00057     parse(str.c_str(),tg,space_p);
00058     
00059     tree<std::string> tmp(tr);
00060     tr.clear();
00061     return tmp;
00062   }
00063 } //~namespace
00064 
00065 std::istream& operator>>(std::istream& in,opencog::tree<std::string>& t) throw (InconsistenceException, std::bad_exception) {
00066   t.clear();
00067   std::string str,tmp;
00068   int nparen=0;
00069   do {
00070     //replaced by getline so that a message i.e. "yo  man" isn't
00071     //replaced by "yo man" (where a space is missing)
00072     //Other assumption : no '(' and ')' between " "
00073     std::getline(in, tmp);
00074     nparen+=count(tmp.begin(),tmp.end(),'(')-count(tmp.begin(),tmp.end(),')');
00075     str+=tmp+' ';
00076   } while (in.good() && nparen>0);
00077   if (nparen!=0) {
00078     std::stringstream stream (std::stringstream::out);
00079     stream << "Paren mismatch parsing tree: '" << str << "'" << std::endl;
00080     throw InconsistenceException(TRACE_INFO, "tree - %s.",
00081                  stream.str().c_str());
00082   }
00083   t=parse_string_tree(str);
00084   return in;
00085 }

Generated on Fri Dec 4 23:23:31 2009 for OpenCog Framework by  doxygen 1.5.6