Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

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::lit("::")[qi::_val += "::"] >> inner[qi::_val += qi::_1]
00084         >> *(qi::lit("::") >> inner[qi::_val += ("::"+qi::_1)]);
00085       inner = qi::alpha >> *(qi::alnum | qi::char_('_'));
00086   }
00087 // ----------------------------------------------------------------------------
00088   qi::rule<Iterator, Node(), Skipper> ident;
00089   qi::rule<Iterator, std::string(), Skipper> str;
00090   qi::rule<Iterator, std::string()> inner;
00091   ph::function<NodeOperations> op;
00092 };
00093 // ============================================================================
00094 template<typename Iterator, typename Skipper>
00095 struct BoolGrammar: qi::grammar<Iterator, bool(), Skipper> {
00096 // ----------------------------------------------------------------------------
00097   typedef bool ResultT;
00098 // ----------------------------------------------------------------------------
00099   BoolGrammar() : BoolGrammar::base_type(boolean) {
00100       boolean = enc::no_case[
00101                              qi::lit("true")[qi::_val=true]
00102                              |
00103                              qi::lit("false")[qi::_val=false]
00104                ];
00105  }
00106 // ----------------------------------------------------------------------------
00107   qi::rule<Iterator, bool(), Skipper> boolean;
00108 };
00109 // ============================================================================
00110 template<typename Iterator, typename Skipper>
00111 struct RealGrammar: qi::grammar<Iterator, Node(), Skipper> {
00112 // ----------------------------------------------------------------------------
00113   typedef bool ResultT;
00114 //---------------------------------------------------------------------
00115   RealGrammar() : RealGrammar::base_type(real) {
00116       real = qi::raw[qi::double_][op(qi::_val, qi::_1)]
00117                    [op(qi::_val, Node::kReal)]
00118                      >> -(-qi::char_('*') >> gunit[op(qi::_val,qi::_1)]);
00119 
00120   }
00121 // ----------------------------------------------------------------------------
00122   qi::rule<Iterator, Node(), Skipper> real;
00123   IdentifierGrammar<Iterator,Skipper> gunit;
00124   ph::function<NodeOperations> op;
00125 };
00126 // ============================================================================
00127 template<typename Iterator, typename Skipper>
00128 struct UnitsGrammar: qi::grammar<Iterator, Node(), Skipper> {
00129 // ----------------------------------------------------------------------------
00130   UnitsGrammar() : UnitsGrammar::base_type(units) {
00131       units = *unit[op(qi::_val, qi::_1)];
00132       unit = rep::qi::iter_pos[op(qi::_val, qi::_1)] >>
00133              val[op(qi::_val, qi::_1)]
00134                      >> -qi::lit('*') >> gunit[op(qi::_val, qi::_1)]
00135                      >> qi::lit('=') >> val[op(qi::_val, qi::_1)]
00136                                             [op(qi::_val, Node::kUnit)];;
00137       val = qi::raw[qi::double_]
00138                             [op(qi::_val, qi::_1)][op(qi::_val, Node::kReal)];
00139 
00140   }
00141 // ----------------------------------------------------------------------------
00142   qi::rule<Iterator, Node(), Skipper> units, unit, val;
00143   IdentifierGrammar<Iterator,Skipper> gunit;
00144   ph::function<NodeOperations> op;
00145 };
00146 // ============================================================================
00147 template<typename Iterator, typename Skipper>
00148 struct FileGrammar: qi::grammar<Iterator, Node(), Skipper> {
00149   FileGrammar() : FileGrammar::base_type(file) {
00150       file = -shell[op(qi::_val,qi::_1)] >>
00151               *(statement[op(qi::_val, qi::_1)])
00152               [op(qi::_val, Node::kRoot)];
00153       shell = rep::confix("#!", qi::eol)[*(qi::char_[qi::_a += qi::_1]
00154                       - qi::eol)][op(qi::_val,Node::kShell)]
00155                       [op(qi::_val,qi::_a)];
00156       statement = rep::qi::iter_pos[qi::_a = qi::_1]
00157                     >> (include | assign | units | print_options | pragma
00158                         | condition)[qi::_val = qi::_1][op(qi::_val,qi::_a)];
00159       condition = (qi::lit("#ifdef")[op(qi::_a,Node::kIfdef)]
00160                         | qi::lit("#ifndef")[op(qi::_a,Node::kIfndef)])
00161                         >> property[op(qi::_val,qi::_1)]
00162                         >> (*statement[op(qi::_a,qi::_1)])[op(qi::_val, qi::_a)]
00163                         >> -(qi::lit("#else")[op(qi::_b,Node::kElse)]
00164                           >> *statement[op(qi::_b,qi::_1)])[op(qi::_val,qi::_b)]
00165                         >> qi::lit("#endif")[op(qi::_val, Node::kCondition)];
00166       include = qi::lit("#include")
00167                       >> gstring[op(qi::_val, qi::_1)]
00168                                 [op(qi::_val, Node::kInclude)];
00169       units = qi::lit("#units")
00170                       >> gstring[op(qi::_val, qi::_1)]
00171                                 [op(qi::_val, Node::kUnits)];
00172       print_options = qi::lit("#printOptions") >> qi::lit("full")
00173                     [op(qi::_val, Node::kPrintOptions)];
00174       pragma = qi::lit("#pragma") >> (pragma_print | pragma_tree |
00175           pragma_dump_file);
00176       pragma_print = qi::lit("print") >> enc::no_case[
00177         qi::lit("on")[op(qi::_val, Node::kPrintOn)]
00178         | qi::lit("off")[op(qi::_val, Node::kPrintOff)]
00179       ];
00180       pragma_tree = enc::no_case[
00181                      qi::lit("printtree")[op(qi::_val, Node::kPrintTree)]
00182                     ];
00183       pragma_dump_file  = qi::lit("dumpfile") >> gstring[op(qi::_val, qi::_1)]
00184                                                 [op(qi::_val, Node::kDumpFile)];
00185       assign = property[op(qi::_val, qi::_1)]
00186                              [op(qi::_val, Node::kAssign)]
00187                       >> oper[op(qi::_val, qi::_1)]
00188                       >> value[op(qi::_val, qi::_1)]
00189                       >> ';';
00190       property = rep::qi::iter_pos[op(qi::_val, qi::_1)]
00191                          >> (gidentifier[op(qi::_val, qi::_1)] % '.')
00192                         [op(qi::_val, Node::kProperty)];
00193       property_ref %= -qi::lit('@') >>
00194           property[op(qi::_val, Node::kPropertyRef)];
00195       oper = rep::qi::iter_pos[op(qi::_val, qi::_1)]
00196                    >> (qi::lit("=")[op(qi::_val, Node::kEqual)]
00197                         |
00198                         qi::lit("+=")[op(qi::_val, Node::kPlusEqual)]
00199                         |
00200                         qi::lit("-=")[op(qi::_val, Node::kMinusEqual)]);
00201       value = rep::qi::iter_pos[qi::_a =  qi::_1]
00202                      >>
00203                      (map_value | vector_value |  simple_value | property |
00204                          property_ref)
00205                      [qi::_val = qi::_1][op(qi::_val, qi::_a)]
00206                      ;
00207       begin_vector = enc::char_('(')[qi::_val=')']
00208                            |
00209                            enc::char_('[')[qi::_val=']']
00210                            |
00211                            enc::char_('{')[qi::_val='}'];
00212       end_vector = qi::char_(qi::_r1);
00213       vector_value = (begin_vector[qi::_a = qi::_1]
00214                              >> -(value[op(qi::_val,qi::_1)] % ',')
00215                                >> end_vector(qi::_a)
00216                            )[op(qi::_val,Node::kVector)];
00217       map_value = (enc::char_('{')
00218                     >> -(pair[op(qi::_val, qi::_1)] % ',')
00219                         >> enc::char_('}'))
00220                     [op(qi::_val, Node::kMap)];
00221       pair = simple_value[op(qi::_val,qi::_1)] >> ':'
00222                     >> value[op(qi::_val,qi::_1)]
00223                      [op(qi::_val,Node::kPair)];
00224       simple_value =
00225                     (gstring[op(qi::_val, qi::_1)][op(qi::_val, Node::kString)])
00226                     |
00227                     (gbool[op(qi::_val, qi::_1)][op(qi::_val, Node::kBool)])
00228                     |
00229                     (greal[qi::_val = qi::_1]);
00230   }
00231   qi::rule<Iterator, Node(), Skipper> file, include, assign, property,
00232           property_ref, oper, map_value, pair_value, simple_value, pair, units,
00233           print_options, pragma, pragma_print, pragma_tree, pragma_dump_file;
00234   qi::rule<Iterator, Node(),qi::locals<std::string> > shell;
00235   qi::rule<Iterator, Node(), qi::locals<Iterator>, Skipper> statement, value;
00236   qi::rule<Iterator, Node(), qi::locals<char>, Skipper> vector_value;
00237   qi::rule<Iterator, Node(), qi::locals<Node, Node>, Skipper> condition;
00238   qi::rule<Iterator, char()> begin_vector;
00239   qi::rule<Iterator, void(char)> end_vector;
00240   StringGrammar<Iterator, Skipper> gstring;
00241   BoolGrammar<Iterator, Skipper> gbool;
00242   RealGrammar<Iterator, Skipper> greal;
00243   IdentifierGrammar<Iterator, Skipper> gidentifier;
00244   ph::function<NodeOperations> op;
00245 };
00246 // ============================================================================
00247 }  /* Gaudi */ } /* Parsers */
00248 // ============================================================================
00249 #endif  // JOBOPTIONSVC_GRAMMAR_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Sep 17 2012 13:49:28 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004