Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

Grammar.h

Go to the documentation of this file.
00001 #ifndef JOBOPTIONSVC_GRAMMAR_H_
00002 #define JOBOPTIONSVC_GRAMMAR_H_
00003 // ============================================================================
00004 // Includes:
00005 // ============================================================================
00006 // STD & STL:
00007 // ============================================================================
00008 #include <string>
00009 #include <vector>
00010 #include <map>
00011 // ============================================================================
00012 // Boost:
00013 // ============================================================================
00014 #include <boost/spirit/include/qi.hpp>
00015 #include <boost/spirit/include/phoenix_core.hpp>
00016 #include <boost/spirit/include/phoenix_fusion.hpp>
00017 #include <boost/spirit/include/phoenix_operator.hpp>
00018 #include <boost/spirit/include/phoenix_stl.hpp>
00019 #include <boost/spirit/repository/include/qi_confix.hpp>
00020 
00021 #if BOOST_VERSION <= 104400
00022 #include "iter_pos.hpp"
00023 #else
00024 #include <boost/spirit/repository/include/qi_iter_pos.hpp>
00025 #endif
00026 
00027 // ============================================================================
00028 //  Project:
00029 // ============================================================================
00030 #include "Node.h"
00031 //============================================================================
00032 namespace Gaudi { namespace Parsers {
00033 // ============================================================================
00034 // Namespace aliases:
00035 // ============================================================================
00036 namespace sp = boost::spirit;
00037 namespace ph = boost::phoenix;
00038 namespace qi = sp::qi;
00039 namespace enc = sp::ascii;
00040 namespace rep = sp::repository;
00041 //=============================================================================
00042 // Grammars
00043 //=============================================================================
00044 template<typename Iterator>
00045 struct SkipperGrammar: qi::grammar<Iterator> {
00046   SkipperGrammar() : SkipperGrammar::base_type(comments) {
00047       comments = enc::space
00048               | rep::confix("/*", "*/")[*(qi::char_ - "*/")]
00049               | rep::confix("//", (sp::eol | sp::eoi))[*(qi::char_ - (sp::eol | sp::eoi))];
00050   }
00051   qi::rule<Iterator> comments;
00052 };
00053 // ============================================================================
00054 template<typename Iterator, typename Skipper>
00055 struct StringGrammar: qi::grammar<Iterator, std::string(), qi::locals<char>,
00056   Skipper> {
00057   //---------------------------------------------------------------------------
00058   typedef std::string ResultT;
00059         //---------------------------------------------------------------------
00060   StringGrammar() : StringGrammar::base_type(str) {
00061       begin_quote = enc::char_("\"'");
00062       quote = enc::char_(qi::_r1);
00063 
00064       str = qi::lexeme[begin_quote[qi::_a = qi::_1] >> *((enc::char_('\\')
00065           >> quote(qi::_a))[qi::_val += qi::_a]
00066           | (enc::char_[qi::_val += qi::_1] - quote(qi::_a)))
00067           >> quote(qi::_a)];
00068   }
00069 //-----------------------------------------------------------------------------
00070   qi::rule<Iterator, std::string(), qi::locals<char>, Skipper> str;
00071   qi::rule<Iterator, char()> begin_quote;
00072   qi::rule<Iterator, void(char)> quote;
00073 //-----------------------------------------------------------------------------
00074 };
00075 // ============================================================================
00076 template<typename Iterator, typename Skipper>
00077 struct IdentifierGrammar: qi::grammar<Iterator, Node(), Skipper> {
00078 //-----------------------------------------------------------------------------
00079   typedef std::string ResultT;
00080 //-----------------------------------------------------------------------------
00081   IdentifierGrammar() : IdentifierGrammar::base_type(ident) {
00082       ident = rep::qi::iter_pos[op(qi::_val, qi::_1)] >> str[op(qi::_val, qi::_1)][op(qi::_val, Node::kIdentifier)];
00083       str = qi::lexeme[qi::alpha >> *(qi::alnum | '_')];
00084   }
00085 // ----------------------------------------------------------------------------
00086   qi::rule<Iterator, Node(), Skipper> ident;
00087   qi::rule<Iterator, std::string(), Skipper> str;
00088   ph::function<NodeOperations> op;
00089 };
00090 // ============================================================================
00091 template<typename Iterator, typename Skipper>
00092 struct BoolGrammar: qi::grammar<Iterator, bool(), Skipper> {
00093 // ----------------------------------------------------------------------------
00094   typedef bool ResultT;
00095 // ----------------------------------------------------------------------------
00096   BoolGrammar() : BoolGrammar::base_type(boolean) {
00097       boolean = enc::no_case[
00098                              qi::lit("true")[qi::_val=true]
00099                              |
00100                              qi::lit("false")[qi::_val=false]
00101                ];
00102  }
00103 // ----------------------------------------------------------------------------
00104   qi::rule<Iterator, bool(), Skipper> boolean;
00105 };
00106 // ============================================================================
00107 template<typename Iterator, typename Skipper>
00108 struct RealGrammar: qi::grammar<Iterator, Node(), Skipper> {
00109 // ----------------------------------------------------------------------------
00110   typedef bool ResultT;
00111 //---------------------------------------------------------------------
00112   RealGrammar() : RealGrammar::base_type(real) {
00113       real = qi::raw[qi::double_][op(qi::_val, qi::_1)]
00114                    [op(qi::_val, Node::kReal)]
00115                      >> -(-qi::char_('*') >> gunit[op(qi::_val,qi::_1)]);
00116 
00117   }
00118 // ----------------------------------------------------------------------------
00119   qi::rule<Iterator, Node(), Skipper> real;
00120   IdentifierGrammar<Iterator,Skipper> gunit;
00121   ph::function<NodeOperations> op;
00122 };
00123 // ============================================================================
00124 template<typename Iterator, typename Skipper>
00125 struct UnitsGrammar: qi::grammar<Iterator, Node(), Skipper> {
00126 // ----------------------------------------------------------------------------
00127   UnitsGrammar() : UnitsGrammar::base_type(units) {
00128       units = *unit[op(qi::_val, qi::_1)];
00129       unit = rep::qi::iter_pos[op(qi::_val, qi::_1)] >>
00130              val[op(qi::_val, qi::_1)]
00131                      >> -qi::lit('*') >> gunit[op(qi::_val, qi::_1)]
00132                      >> qi::lit('=') >> val[op(qi::_val, qi::_1)]
00133                                             [op(qi::_val, Node::kUnit)];;
00134       val = qi::raw[qi::double_]
00135                             [op(qi::_val, qi::_1)][op(qi::_val, Node::kReal)];
00136 
00137   }
00138 // ----------------------------------------------------------------------------
00139   qi::rule<Iterator, Node(), Skipper> units, unit, val;
00140   IdentifierGrammar<Iterator,Skipper> gunit;
00141   ph::function<NodeOperations> op;
00142 };
00143 // ============================================================================
00144 template<typename Iterator, typename Skipper>
00145 struct FileGrammar: qi::grammar<Iterator, Node(), Skipper> {
00146   FileGrammar() : FileGrammar::base_type(file) {
00147       file = -shell[op(qi::_val,qi::_1)] >>
00148               *(statement[op(qi::_val, qi::_1)])
00149               [op(qi::_val, Node::kRoot)];
00150       shell = rep::confix("#!", qi::eol)[*(qi::char_[qi::_a += qi::_1]
00151                       - qi::eol)][op(qi::_val,Node::kShell)]
00152                       [op(qi::_val,qi::_a)];
00153       statement = rep::qi::iter_pos[qi::_a = qi::_1]
00154                     >> (include | assign | units | print_options | pragma
00155                         | condition)[qi::_val = qi::_1][op(qi::_val,qi::_a)];
00156       condition = (qi::lit("#ifdef")[op(qi::_a,Node::kIfdef)]
00157                         | qi::lit("#ifndef")[op(qi::_a,Node::kIfndef)])
00158                         >> property[op(qi::_val,qi::_1)]
00159                         >> (*statement[op(qi::_a,qi::_1)])[op(qi::_val, qi::_a)]
00160                         >> -(qi::lit("#else")[op(qi::_b,Node::kElse)]
00161                           >> *statement[op(qi::_b,qi::_1)])[op(qi::_val,qi::_b)]
00162                         >> qi::lit("#endif")[op(qi::_val, Node::kCondition)];
00163       include = qi::lit("#include")
00164                       >> gstring[op(qi::_val, qi::_1)]
00165                                 [op(qi::_val, Node::kInclude)];
00166       units = qi::lit("#units")
00167                       >> gstring[op(qi::_val, qi::_1)]
00168                                 [op(qi::_val, Node::kUnits)];
00169       print_options = qi::lit("#printOptions") >> qi::lit("full")
00170                     [op(qi::_val, Node::kPrintOptions)];
00171       pragma = qi::lit("#pragma") >> (pragma_print | pragma_tree |
00172           pragma_dump_file);
00173       pragma_print = qi::lit("print") >> enc::no_case[
00174         qi::lit("on")[op(qi::_val, Node::kPrintOn)]
00175         | qi::lit("off")[op(qi::_val, Node::kPrintOff)]
00176       ];
00177       pragma_tree = enc::no_case[
00178                      qi::lit("printtree")[op(qi::_val, Node::kPrintTree)]
00179                     ];
00180       pragma_dump_file  = qi::lit("dumpfile") >> gstring[op(qi::_val, qi::_1)]
00181                                                 [op(qi::_val, Node::kDumpFile)];
00182       assign = property[op(qi::_val, qi::_1)]
00183                              [op(qi::_val, Node::kAssign)]
00184                       >> oper[op(qi::_val, qi::_1)]
00185                       >> value[op(qi::_val, qi::_1)]
00186                       >> ';';
00187       property = rep::qi::iter_pos[op(qi::_val, qi::_1)]
00188                          >> (gidentifier[op(qi::_val, qi::_1)]
00189                          >> -(gidentifier[op(qi::_val, qi::_1)]) % '.')
00190                     [op(qi::_val, Node::kProperty)];
00191       property_ref %= -qi::lit('@') >>
00192           property[op(qi::_val, Node::kPropertyRef)];
00193       oper = rep::qi::iter_pos[op(qi::_val, qi::_1)]
00194                    >> (qi::lit("=")[op(qi::_val, Node::kEqual)]
00195                         |
00196                         qi::lit("+=")[op(qi::_val, Node::kPlusEqual)]
00197                         |
00198                         qi::lit("-=")[op(qi::_val, Node::kMinusEqual)]);
00199       value = rep::qi::iter_pos[qi::_a =  qi::_1]
00200                      >>
00201                      (map_value | vector_value |  simple_value | property |
00202                          property_ref)
00203                      [qi::_val = qi::_1][op(qi::_val, qi::_a)]
00204                      ;
00205       begin_vector = enc::char_('(')[qi::_val=')']
00206                            |
00207                            enc::char_('[')[qi::_val=']']
00208                            |
00209                            enc::char_('{')[qi::_val='}'];
00210       end_vector = qi::char_(qi::_r1);
00211       vector_value = (begin_vector[qi::_a = qi::_1]
00212                              >> -(value[op(qi::_val,qi::_1)] % ',')
00213                                >> end_vector(qi::_a)
00214                            )[op(qi::_val,Node::kVector)];
00215       map_value = (enc::char_('{')
00216                     >> -(pair[op(qi::_val, qi::_1)] % ',')
00217                         >> enc::char_('}'))
00218                     [op(qi::_val, Node::kMap)];
00219       pair = simple_value[op(qi::_val,qi::_1)] >> ':'
00220                     >> value[op(qi::_val,qi::_1)]
00221                      [op(qi::_val,Node::kPair)];
00222       simple_value =
00223                     (gstring[op(qi::_val, qi::_1)][op(qi::_val, Node::kString)])
00224                     |
00225                     (gbool[op(qi::_val, qi::_1)][op(qi::_val, Node::kBool)])
00226                     |
00227                     (greal[qi::_val = qi::_1]);
00228   }
00229   qi::rule<Iterator, Node(), Skipper> file, include, assign, property,
00230           property_ref, oper, map_value, pair_value, simple_value, pair, units,
00231           print_options, pragma, pragma_print, pragma_tree, pragma_dump_file;
00232   qi::rule<Iterator, Node(),qi::locals<std::string> > shell;
00233   qi::rule<Iterator, Node(), qi::locals<Iterator>, Skipper> statement, value;
00234   qi::rule<Iterator, Node(), qi::locals<char>, Skipper> vector_value;
00235   qi::rule<Iterator, Node(), qi::locals<Node, Node>, Skipper> condition;
00236   qi::rule<Iterator, char()> begin_vector;
00237   qi::rule<Iterator, void(char)> end_vector;
00238   StringGrammar<Iterator, Skipper> gstring;
00239   BoolGrammar<Iterator, Skipper> gbool;
00240   RealGrammar<Iterator, Skipper> greal;
00241   IdentifierGrammar<Iterator, Skipper> gidentifier;
00242   ph::function<NodeOperations> op;
00243 };
00244 // ============================================================================
00245 }  /* Gaudi */ } /* Parsers */
00246 // ============================================================================
00247 #endif  // JOBOPTIONSVC_GRAMMAR_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Fri Sep 2 2011 16:24:57 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004