00001 #ifndef Utilities_Grammar_h
00002 #define Utilities_Grammar_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "boost/spirit/core.hpp"
00014 #include "boost/spirit/utility/grammar_def.hpp"
00015 #include "boost/spirit/utility/chset.hpp"
00016 #include <functional>
00017 #include "PhysicsTools/Utilities/src/ExpressionNumberSetter.h"
00018 #include "PhysicsTools/Utilities/src/ExpressionVarSetter.h"
00019 #include "PhysicsTools/Utilities/src/ExpressionFunctionSetter.h"
00020 #include "PhysicsTools/Utilities/src/ComparisonSetter.h"
00021 #include "PhysicsTools/Utilities/src/BinarySelectorSetter.h"
00022 #include "PhysicsTools/Utilities/src/TrinarySelectorSetter.h"
00023 #include "PhysicsTools/Utilities/src/IntSetter.h"
00024 #include "PhysicsTools/Utilities/src/MethodStack.h"
00025 #include "PhysicsTools/Utilities/src/MethodArgumentStack.h"
00026 #include "PhysicsTools/Utilities/src/TypeStack.h"
00027 #include "PhysicsTools/Utilities/src/IntStack.h"
00028 #include "PhysicsTools/Utilities/src/FunctionSetter.h"
00029 #include "PhysicsTools/Utilities/src/CutSetter.h"
00030 #include "PhysicsTools/Utilities/src/BinaryCutSetter.h"
00031 #include "PhysicsTools/Utilities/src/UnaryCutSetter.h"
00032 #include "PhysicsTools/Utilities/src/ExpressionSetter.h"
00033 #include "PhysicsTools/Utilities/src/ExpressionBinaryOperatorSetter.h"
00034 #include "PhysicsTools/Utilities/src/ExpressionUnaryOperatorSetter.h"
00035 #include "PhysicsTools/Utilities/src/ExpressionSelectorSetter.h"
00036 #include "PhysicsTools/Utilities/src/MethodSetter.h"
00037 #include "PhysicsTools/Utilities/src/MethodArgumentSetter.h"
00038 #include "PhysicsTools/Utilities/interface/Exception.h"
00039
00040
00041 namespace reco {
00042 namespace parser {
00043 struct Grammar : public boost::spirit::grammar<Grammar> {
00044
00045 SelectorPtr dummySel_;
00046 ExpressionPtr dummyExpr_;
00047 SelectorPtr * sel_;
00048 ExpressionPtr * expr_;
00049 mutable ExpressionStack exprStack;
00050 mutable ComparisonStack cmpStack;
00051 mutable SelectorStack selStack;
00052 mutable FunctionStack funStack;
00053 mutable MethodStack methStack;
00054 mutable MethodArgumentStack methArgStack;
00055 mutable TypeStack typeStack;
00056 mutable IntStack intStack;
00057 template<typename T>
00058 Grammar(SelectorPtr & sel, const T *) :
00059 sel_(& sel), expr_(& dummyExpr_) {
00060 typeStack.push_back(ROOT::Reflex::Type::ByTypeInfo(typeid(T)));
00061 }
00062 template<typename T>
00063 Grammar(ExpressionPtr & expr, const T*) :
00064 sel_(& dummySel_), expr_(& expr) {
00065 typeStack.push_back(ROOT::Reflex::Type::ByTypeInfo(typeid(T)));
00066 }
00067 Grammar(SelectorPtr & sel, const ROOT::Reflex::Type& iType) :
00068 sel_(& sel), expr_(& dummyExpr_) {
00069 typeStack.push_back(iType);
00070 }
00071 template<typename T>
00072 Grammar(ExpressionPtr & expr, const ROOT::Reflex::Type& iType) :
00073 sel_(& dummySel_), expr_(& expr) {
00074 typeStack.push_back(iType);
00075 }
00076 template <typename ScannerT>
00077 struct definition :
00078 public boost::spirit::grammar_def<boost::spirit::rule<ScannerT>,
00079 boost::spirit::same,
00080 boost::spirit::same>{
00081 typedef boost::spirit::rule<ScannerT> rule;
00082 rule number, var, metharg, method, term, power, factor, function1, function2, expression,
00083 comparison_op, binary_comp, trinary_comp,
00084 logical_combiner, logical_expression, logical_factor, logical_term,
00085 or_op, and_op, cut, fun;
00086 definition(const Grammar & self) {
00087 using namespace boost::spirit;
00088 using namespace std;
00089
00090 ExpressionNumberSetter number_s(self.exprStack);
00091 IntSetter int_s(self.intStack);
00092 ExpressionVarSetter var_s(self.exprStack, self.methStack, self.typeStack);
00093 MethodArgumentSetter methodArg_s(self.methArgStack);
00094 MethodSetter method_s(self.methStack, self.typeStack, self.methArgStack);
00095 ComparisonSetter<less_equal<double> > less_equal_s(self.cmpStack);
00096 ComparisonSetter<less<double> > less_s(self.cmpStack);
00097 ComparisonSetter<equal_to<double> > equal_to_s(self.cmpStack);
00098 ComparisonSetter<greater_equal<double> > greater_equal_s(self.cmpStack);
00099 ComparisonSetter<greater<double> > greater_s(self.cmpStack);
00100 ComparisonSetter<not_equal_to<double> > not_equal_to_s(self.cmpStack);
00101 FunctionSetter
00102 abs_s(kAbs, self.funStack), acos_s(kAcos, self.funStack), asin_s(kAsin, self.funStack),
00103 atan_s(kAtan, self.funStack), atan2_s(kAtan, self.funStack),
00104 chi2prob_s(kChi2Prob, self.funStack),
00105 cos_s(kCos, self.funStack),
00106 cosh_s(kCosh, self.funStack), exp_s(kExp, self.funStack), log_s(kLog, self.funStack),
00107 log10_s(kLog10, self.funStack), max_s(kMax, self.funStack), min_s(kMin, self.funStack),
00108 pow_s(kPow, self.funStack), sin_s(kSin, self.funStack),
00109 sinh_s(kSinh, self.funStack), sqrt_s(kSqrt, self.funStack), tan_s(kTan, self.funStack),
00110 tanh_s(kTanh, self.funStack);
00111 TrinarySelectorSetter trinary_s(self.selStack, self.cmpStack, self.exprStack);
00112 BinarySelectorSetter binary_s(self.selStack, self.cmpStack, self.exprStack);
00113 ExpressionSelectorSetter expr_sel_s(self.selStack, self.exprStack);
00114 BinaryCutSetter<logical_and<bool> > and_s(self.selStack);
00115 BinaryCutSetter<logical_or<bool> > or_s(self.selStack);
00116 UnaryCutSetter<logical_not<bool> > not_s(self.selStack);
00117 CutSetter cut_s(* self.sel_, self.selStack);
00118 ExpressionSetter expr_s(* self.expr_, self.exprStack);
00119 ExpressionBinaryOperatorSetter<plus<double> > plus_s(self.exprStack);
00120 ExpressionBinaryOperatorSetter<minus<double> > minus_s(self.exprStack);
00121 ExpressionBinaryOperatorSetter<multiplies<double> > multiplies_s(self.exprStack);
00122 ExpressionBinaryOperatorSetter<divides<double> > divides_s(self.exprStack);
00123 ExpressionBinaryOperatorSetter<power_of<double> > power_of_s(self.exprStack);
00124 ExpressionUnaryOperatorSetter<negate<double> > negate_s(self.exprStack);
00125 ExpressionFunctionSetter fun_s(self.exprStack, self.funStack);
00126
00127 BOOST_SPIRIT_DEBUG_RULE(var);
00128 BOOST_SPIRIT_DEBUG_RULE(method);
00129 BOOST_SPIRIT_DEBUG_RULE(logical_expression);
00130 BOOST_SPIRIT_DEBUG_RULE(logical_term);
00131 BOOST_SPIRIT_DEBUG_RULE(logical_factor);
00132 BOOST_SPIRIT_DEBUG_RULE(number);
00133 BOOST_SPIRIT_DEBUG_RULE(metharg);
00134 BOOST_SPIRIT_DEBUG_RULE(function1);
00135 BOOST_SPIRIT_DEBUG_RULE(function2);
00136 BOOST_SPIRIT_DEBUG_RULE(expression);
00137 BOOST_SPIRIT_DEBUG_RULE(term);
00138 BOOST_SPIRIT_DEBUG_RULE(power);
00139 BOOST_SPIRIT_DEBUG_RULE(factor);
00140 BOOST_SPIRIT_DEBUG_RULE(or_op);
00141 BOOST_SPIRIT_DEBUG_RULE(and_op);
00142 BOOST_SPIRIT_DEBUG_RULE(comparison_op);
00143 BOOST_SPIRIT_DEBUG_RULE(binary_comp);
00144 BOOST_SPIRIT_DEBUG_RULE(trinary_comp);
00145 BOOST_SPIRIT_DEBUG_RULE(cut);
00146 BOOST_SPIRIT_DEBUG_RULE(fun);
00147
00148 boost::spirit::assertion<SyntaxErrors> expectParenthesis(kMissingClosingParenthesis);
00149 boost::spirit::assertion<SyntaxErrors> expect(kSyntaxError);
00150
00151 number =
00152 real_p [ number_s ];
00153 metharg = ( strict_real_p [ methodArg_s ] ) |
00154 ( int_p [ methodArg_s ] ) |
00155 ( ch_p('"' ) >> *(~ch_p('"' )) >> ch_p('"' ) ) [ methodArg_s ] |
00156 ( ch_p('\'') >> *(~ch_p('\'')) >> ch_p('\'') ) [ methodArg_s ];
00157 var =
00158 (alpha_p >> * chset<>("a-zA-Z0-9_") >>
00159 ch_p('(') >> metharg >> * (ch_p(',') >> metharg ) >> expectParenthesis(ch_p(')'))) [ method_s ] |
00160 ( (alpha_p >> * chset<>("a-zA-Z0-9_")) [ method_s ] >> ! (ch_p('(') >> ch_p(')')) ) ;
00161 method =
00162 (var >> * ((ch_p('.') >> expect(var)))) [ var_s ];
00163 function1 =
00164 chseq_p("abs") [ abs_s ] | chseq_p("acos") [ acos_s ] | chseq_p("asin") [ asin_s ] |
00165 chseq_p("atan") [ atan_s ] | chseq_p("cos") [ cos_s ] | chseq_p("cosh") [ cosh_s ] |
00166 chseq_p("exp") [ exp_s ] | chseq_p("log") [ log_s ] | chseq_p("log10") [ log10_s ] |
00167 chseq_p("sin") [ sin_s ] | chseq_p("sinh") [ sinh_s ] | chseq_p("sqrt") [ sqrt_s ] |
00168 chseq_p("tan") [ tan_s ] | chseq_p("tanh") [ tanh_s ];
00169 function2 =
00170 chseq_p("atan2") [ atan2_s ] | chseq_p("chi2prob") [ chi2prob_s ] | chseq_p("pow") [ pow_s ] |
00171 chseq_p("min") [ min_s ] | chseq_p("max") [ max_s ];
00172 expression =
00173 term >> * (('+' >> expect(term)) [ plus_s ] |
00174 ('-' >> expect(term)) [ minus_s ]);
00175 term =
00176 power >> * (('*' >> expect(power)) [ multiplies_s ] |
00177 ('/' >> expect(power)) [ divides_s ]);
00178 power =
00179 factor >> * (('^' >> expect(factor)) [ power_of_s ]);
00180 factor =
00181 number |
00182 (function1 >> ch_p('(') >> expect(expression) >> expectParenthesis(ch_p(')'))) [ fun_s ] |
00183 (function2 >> ch_p('(') >> expect(expression) >>
00184 expect(ch_p(',')) >> expect(expression) >> expectParenthesis(ch_p(')'))) [ fun_s ] |
00185
00186 method |
00187
00188
00189
00190
00191
00192
00193
00194 ch_p('(') >> expression >> ch_p(')') |
00195 (ch_p('-') >> factor) [ negate_s ] |
00196 (ch_p('+') >> factor);
00197 comparison_op =
00198 (ch_p('<') >> ch_p('=') [ less_equal_s ]) |
00199 (ch_p('<') [ less_s ]) |
00200 (ch_p('=') >> ch_p('=') [ equal_to_s ]) |
00201 (ch_p('=') [ equal_to_s ]) |
00202 (ch_p('>') >> ch_p('=') [ greater_equal_s ]) |
00203 (ch_p('>') [ greater_s ]) |
00204 (ch_p('!') >> ch_p('=') [ not_equal_to_s ]);
00205 binary_comp =
00206 (expression >> comparison_op >> expect(expression)) [ binary_s ];
00207 trinary_comp =
00208 (expression >> comparison_op >> expect(expression) >> comparison_op >> expect(expression)) [ trinary_s ];
00209 or_op = ch_p('|') >> ch_p('|') | ch_p('|');
00210 and_op = ch_p('&') >> ch_p('&') | ch_p('&');
00211 logical_expression =
00212 logical_term >> * (or_op >> expect(logical_term)) [ or_s ];
00213 logical_term =
00214 logical_factor >> * (and_op >> expect(logical_factor)) [ and_s ];
00215 logical_factor =
00216 trinary_comp |
00217 binary_comp |
00218 ch_p('(') >> logical_expression >> expectParenthesis(ch_p(')')) |
00219 (ch_p('!') >> expect(logical_factor)) [ not_s ] |
00220 expression [ expr_sel_s ];
00221 ;
00222 cut = logical_expression [ cut_s ];
00223 fun = expression [ expr_s ];
00224 start_parsers(cut, fun);
00225 }
00226 };
00227 };
00228 }
00229 }
00230
00231
00232 #endif