GraphPropertiesParser.cc

Go to the documentation of this file.
00001 // $Id: GraphPropertiesParser.cc 165 2006-05-29 16:39:53Z bingmann $
00002 
00003 // #define BOOST_SPIRIT_DEBUG
00004 
00005 #include <boost/spirit/core.hpp>
00006 
00007 #include <boost/spirit/utility/escape_char.hpp>
00008 #include <boost/spirit/utility/confix.hpp>
00009 #include <boost/spirit/utility/distinct.hpp>
00010 
00011 #include <boost/spirit/phoenix.hpp>
00012 
00013 #include "GraphProperties.h"
00014 #include "AttributeProperties.h"
00015 #include "GraphTypes.h"
00016 
00017 #include <string>
00018 
00019 namespace VGServer {
00020 
00021 using namespace boost::spirit;
00022 using namespace phoenix;
00023 
00050 static member_function_ptr<void, AttributeProperties, attrtype_t> phx_AnyType_resetType = &AttributeProperties::resetType;
00051 static member_function_ptr<bool, AttributeProperties, int> phx_AnyType_setInteger = &AttributeProperties::setInteger;
00052 static member_function_ptr<bool, AttributeProperties, double> phx_AnyType_setDouble = &AttributeProperties::setDouble;
00053 static member_function_ptr<bool, AttributeProperties, const std::string&> phx_AnyType_setString = &AttributeProperties::setString;
00054 static member_function_ptr<bool, AttributeProperties, const std::string&> phx_AnyType_setStringQuoted = &AttributeProperties::setStringQuoted;
00055 
00056 const distinct_parser<> key_p("0-9a-zA-Z_");
00057 
00058 struct GraphPropertiesParser : public grammar<GraphPropertiesParser>
00059 {
00060     template <typename ScannerT>
00061     struct definition
00062     {
00063         definition(GraphPropertiesParser const& self)
00064         {
00065             // require the three componds to be in order!
00066             r_start = r_directed || r_vertexattr || r_edgeattr;
00067 
00068             // first a single keyword: directed or undirected.
00069             r_directed = key_p("directed")[var(self.gp.directed) = 1]
00070                        | key_p("undirected")[var(self.gp.directed) = 0];
00071             
00072             // then the vertexattr ( .. ) list
00073             r_vertexattr = key_p("vertexattr") >> ch_p('(') >> r_attr[push_back_a(self.gp.vertexattr, ap)] >> r_vertexattrlist;
00074 
00075             r_vertexattrlist = ch_p(')')
00076                              | ch_p(',') >> r_attr[push_back_a(self.gp.vertexattr, ap)] >> r_vertexattrlist;
00077 
00078             r_edgeattr = key_p("edgeattr") >> ch_p('(') >> r_attr[push_back_a(self.gp.edgeattr, ap)] >> r_edgeattrlist;
00079 
00080             r_edgeattrlist = ch_p(')')
00081                            | ch_p(',') >> r_attr[push_back_a(self.gp.edgeattr, ap)] >> r_edgeattrlist;
00082 
00083             // an attribute consist of it's name and the type defintion
00084             r_attr = lexeme_d[+graph_p][var(ap.name) = construct_<std::string>(arg1, arg2)] >> r_attrtype;
00085 
00086             // all types are listed here with the action to set the type on the temporary attribute.
00087             // ! means that the expression is _optional_
00088             r_attrtype =
00089                   (key_p("bool")[phx_AnyType_resetType(var(ap), ATTRTYPE_BOOL)] >> !r_attrdefbool)
00090 
00091                 | (key_p("char")[phx_AnyType_resetType(var(ap), ATTRTYPE_CHAR)] >> !r_attrdefint)
00092                 | (key_p("short")[phx_AnyType_resetType(var(ap), ATTRTYPE_SHORT)] >> !r_attrdefint)
00093                 | (key_p("integer")[phx_AnyType_resetType(var(ap), ATTRTYPE_INTEGER)] >> !r_attrdefint)
00094                 | (key_p("long")[phx_AnyType_resetType(var(ap), ATTRTYPE_LONG)] >> !r_attrdefint)
00095 
00096                 | (key_p("byte")[phx_AnyType_resetType(var(ap), ATTRTYPE_BYTE)] >> !r_attrdefuint)
00097                 | (key_p("word")[phx_AnyType_resetType(var(ap), ATTRTYPE_WORD)] >> !r_attrdefuint)
00098                 | (key_p("dword")[phx_AnyType_resetType(var(ap), ATTRTYPE_DWORD)] >> !r_attrdefuint)
00099                 | (key_p("qword")[phx_AnyType_resetType(var(ap), ATTRTYPE_QWORD)] >> !r_attrdefuint)
00100 
00101                 | (key_p("float")[phx_AnyType_resetType(var(ap), ATTRTYPE_FLOAT)] >> !r_attrdefreal)
00102                 | (key_p("double")[phx_AnyType_resetType(var(ap), ATTRTYPE_DOUBLE)] >> !r_attrdefreal)
00103 
00104                 | (key_p("string")[phx_AnyType_resetType(var(ap), ATTRTYPE_STRING)] >> !r_attrdefstring)
00105                 | (key_p("longstring")[phx_AnyType_resetType(var(ap), ATTRTYPE_LONGSTRING)] >> !r_attrdefstring)
00106                 ;
00107 
00108             // the following are parsers for the default ... values, which can be of different types.
00109 
00110             r_attrdefbool = 
00111                 ( key_p("default") >>
00112                   (key_p("true") | key_p("false") | key_p("yes") | key_p("no"))
00113                   [phx_AnyType_setString(var(ap), construct_<std::string>(arg1, arg2))] 
00114                   |
00115                   key_p("varying")[var(ap.varying) = true]
00116                     );
00117 
00118             r_attrdefint = 
00119                 ( key_p("default") >> int_p[phx_AnyType_setInteger(var(ap), arg1)]
00120                   |
00121                   key_p("varying")[var(ap.varying) = true]
00122                     );
00123 
00124             r_attrdefuint =
00125                 ( key_p("default") >> uint_p[phx_AnyType_setInteger(var(ap), arg1)]
00126                   |
00127                   key_p("varying")[var(ap.varying) = true]
00128                     );
00129 
00130             r_attrdefreal =
00131                 ( key_p("default") >> real_p[phx_AnyType_setDouble(var(ap), arg1)]
00132                   |
00133                   key_p("varying")[var(ap.varying) = true]
00134                     );
00135 
00136             // a string default value must be enclosed in "
00137             r_attrdefstring = key_p("default") >>
00138                 confix_p('"', (*c_escape_ch_p), '"')[phx_AnyType_setStringQuoted(var(ap), construct_<std::string>(arg1, arg2))];
00139 
00140 #ifdef BOOST_SPIRIT_DEBUG
00141             BOOST_SPIRIT_DEBUG_RULE(r_attr);
00142             BOOST_SPIRIT_DEBUG_RULE(r_attrtype);
00143 
00144             BOOST_SPIRIT_DEBUG_RULE(r_attrdefbool);
00145             BOOST_SPIRIT_DEBUG_RULE(r_attrdefint);
00146             BOOST_SPIRIT_DEBUG_RULE(r_attrdefuint);
00147             BOOST_SPIRIT_DEBUG_RULE(r_attrdefreal);
00148             BOOST_SPIRIT_DEBUG_RULE(r_attrdefstring);
00149 #endif
00150         }
00151 
00152         rule<ScannerT> r_start, r_directed,
00153                        r_vertexattr, r_vertexattrlist,
00154                        r_edgeattr, r_edgeattrlist,
00155                        r_attr, r_attrtype,
00156                        r_attrdefbool, r_attrdefint, r_attrdefuint, r_attrdefreal, r_attrdefstring;
00157 
00158         rule<ScannerT> const& start() const
00159         { return r_start; }
00160 
00161         // temporary AttributeProperties object
00162         class AttributeProperties ap;
00163     };
00164 
00165     GraphPropertiesParser(class GraphProperties &_gp)
00166         : gp(_gp)
00167     { }
00168 
00169     // reference to object which is filled with the parsed data
00170     class GraphProperties &gp;
00171 };
00172 
00175 struct GraphPropertiesSkipParser : public grammar<GraphPropertiesSkipParser>
00176 {
00177     template<typename ScannerT>
00178     struct definition
00179     {
00180         definition(const GraphPropertiesSkipParser& /*self*/)
00181         {
00182             skip
00183                 = space_p
00184                 | comment_p("//")
00185                 | comment_p("/*", "*/")
00186                 ;
00187             
00188             #ifdef BOOST_SPIRIT_DEBUG
00189             BOOST_SPIRIT_DEBUG_RULE(skip);
00190             #endif
00191         }
00192         
00193         rule<ScannerT> skip;
00194 
00195         const rule<ScannerT>& start() const {
00196             return skip;
00197         }
00198     };
00199 };
00200 
00201 bool GraphProperties::parseConfigString(const std::string &input)
00202 {
00203     GraphPropertiesParser gpp(*this);
00204     GraphPropertiesSkipParser gpsp;
00205 
00206     return boost::spirit::parse(input.c_str(), gpp, gpsp).full;
00207 }
00208 
00209 } // namespace VGServer
00210 
00211 

Generated on Wed Sep 27 14:34:00 2006 for VGServer by  doxygen 1.4.7