00001 #ifndef JOBOPTIONSVC_GRAMMAR_H_
00002 #define JOBOPTIONSVC_GRAMMAR_H_
00003
00004
00005
00006
00007
00008 #include <string>
00009 #include <vector>
00010 #include <map>
00011
00012
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
00029
00030 #include "Node.h"
00031
00032 namespace Gaudi { namespace Parsers {
00033
00034
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
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 } }
00246
00247 #endif // JOBOPTIONSVC_GRAMMAR_H_