File indexing completed on 2024-04-06 12:01:17
0001 #ifndef CommonTools_Utils_Grammar_h
0002 #define CommonTools_Utils_Grammar_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "boost/spirit/include/classic_core.hpp"
0014 #include "boost/spirit/include/classic_grammar_def.hpp"
0015 #include "boost/spirit/include/classic_chset.hpp"
0016 #include <functional>
0017 #include "CommonTools/Utils/interface/parser/ExpressionNumberSetter.h"
0018 #include "CommonTools/Utils/interface/parser/ExpressionVarSetter.h"
0019 #include "CommonTools/Utils/interface/parser/ExpressionFunctionSetter.h"
0020 #include "CommonTools/Utils/interface/parser/ExpressionConditionSetter.h"
0021 #include "CommonTools/Utils/interface/parser/ComparisonSetter.h"
0022 #include "CommonTools/Utils/interface/parser/BinarySelectorSetter.h"
0023 #include "CommonTools/Utils/interface/parser/TrinarySelectorSetter.h"
0024 #include "CommonTools/Utils/interface/parser/IntSetter.h"
0025 #include "CommonTools/Utils/interface/parser/MethodStack.h"
0026 #include "CommonTools/Utils/interface/parser/MethodArgumentStack.h"
0027 #include "CommonTools/Utils/interface/parser/TypeStack.h"
0028 #include "CommonTools/Utils/interface/parser/IntStack.h"
0029 #include "CommonTools/Utils/interface/parser/FunctionSetter.h"
0030 #include "CommonTools/Utils/interface/parser/CutSetter.h"
0031 #include "CommonTools/Utils/interface/parser/BinaryCutSetter.h"
0032 #include "CommonTools/Utils/interface/parser/UnaryCutSetter.h"
0033 #include "CommonTools/Utils/interface/parser/ExpressionSetter.h"
0034 #include "CommonTools/Utils/interface/parser/ExpressionBinaryOperatorSetter.h"
0035 #include "CommonTools/Utils/interface/parser/ExpressionUnaryOperatorSetter.h"
0036 #include "CommonTools/Utils/interface/parser/ExpressionSelectorSetter.h"
0037 #include "CommonTools/Utils/interface/parser/MethodSetter.h"
0038 #include "CommonTools/Utils/interface/parser/MethodArgumentSetter.h"
0039 #include "CommonTools/Utils/interface/parser/Exception.h"
0040 #include "FWCore/Reflection/interface/TypeWithDict.h"
0041
0042 namespace reco {
0043 namespace parser {
0044 struct Grammar : public boost::spirit::classic::grammar<Grammar> {
0045 SelectorPtr dummySel_;
0046 ExpressionPtr dummyExpr_;
0047 SelectorPtr* sel_;
0048 ExpressionPtr* expr_;
0049 bool lazy_;
0050 mutable ExpressionStack exprStack;
0051 mutable ComparisonStack cmpStack;
0052 mutable SelectorStack selStack;
0053 mutable FunctionStack funStack, finalFunStack;
0054 mutable MethodStack methStack;
0055 mutable LazyMethodStack lazyMethStack;
0056 mutable MethodArgumentStack methArgStack;
0057 mutable TypeStack typeStack;
0058 mutable IntStack intStack;
0059
0060 Grammar(SelectorPtr& sel, const edm::TypeWithDict& iType, bool lazy = false)
0061 : sel_(&sel), expr_(&dummyExpr_), lazy_(lazy) {
0062 typeStack.push_back(iType);
0063 }
0064
0065 Grammar(ExpressionPtr& expr, const edm::TypeWithDict& iType, bool lazy = false)
0066 : sel_(&dummySel_), expr_(&expr), lazy_(lazy) {
0067 typeStack.push_back(iType);
0068 }
0069
0070 template <typename ScannerT>
0071 struct definition : public boost::spirit::classic::grammar_def<boost::spirit::classic::rule<ScannerT>,
0072 boost::spirit::classic::same,
0073 boost::spirit::classic::same> {
0074 typedef boost::spirit::classic::rule<ScannerT> rule;
0075 rule number, var, arrayAccess, metharg, method, term, power, factor, function1, function2, function4,
0076 expression, comparison_op, binary_comp, trinary_comp, logical_combiner, logical_expression,
0077 nocond_expression, cond_expression, logical_factor, logical_term, or_op, and_op, cut, fun;
0078 definition(const Grammar& self) {
0079 using namespace boost::spirit::classic;
0080 using namespace std;
0081
0082 ExpressionNumberSetter number_s(self.exprStack);
0083 IntSetter int_s(self.intStack);
0084 ExpressionVarSetter var_s(self.exprStack, self.methStack, self.lazyMethStack, self.typeStack);
0085 ExpressionConditionSetter cond_s(self.exprStack, self.selStack);
0086 MethodArgumentSetter methodArg_s(self.methArgStack);
0087 MethodSetter method_s(self.methStack, self.lazyMethStack, self.typeStack, self.methArgStack, self.lazy_);
0088 ComparisonSetter<less_equal<double> > less_equal_s(self.cmpStack);
0089 ComparisonSetter<less<double> > less_s(self.cmpStack);
0090 ComparisonSetter<equal_to<double> > equal_to_s(self.cmpStack);
0091 ComparisonSetter<greater_equal<double> > greater_equal_s(self.cmpStack);
0092 ComparisonSetter<greater<double> > greater_s(self.cmpStack);
0093 ComparisonSetter<not_equal_to<double> > not_equal_to_s(self.cmpStack);
0094 FunctionSetter abs_s(kAbs, self.funStack), acos_s(kAcos, self.funStack), asin_s(kAsin, self.funStack),
0095 atan2_s(kAtan, self.funStack), atan_s(kAtan, self.funStack), chi2prob_s(kChi2Prob, self.funStack),
0096 cosh_s(kCosh, self.funStack), cos_s(kCos, self.funStack), exp_s(kExp, self.funStack),
0097 hypot_s(kHypot, self.funStack), log_s(kLog, self.funStack), log10_s(kLog10, self.funStack),
0098 max_s(kMax, self.funStack), min_s(kMin, self.funStack), pow_s(kPow, self.funStack),
0099 sinh_s(kSinh, self.funStack), sin_s(kSin, self.funStack), sqrt_s(kSqrt, self.funStack),
0100 tanh_s(kTanh, self.funStack), tan_s(kTan, self.funStack), deltaPhi_s(kDeltaPhi, self.funStack),
0101 deltaR_s(kDeltaR, self.funStack), test_bit_s(kTestBit, self.funStack);
0102 FunctionSetterCommit funOk_s(self.funStack, self.finalFunStack);
0103 TrinarySelectorSetter trinary_s(self.selStack, self.cmpStack, self.exprStack);
0104 BinarySelectorSetter binary_s(self.selStack, self.cmpStack, self.exprStack);
0105 ExpressionSelectorSetter expr_sel_s(self.selStack, self.exprStack);
0106 BinaryCutSetter<logical_and<bool> > and_s(self.selStack);
0107 BinaryCutSetter<logical_or<bool> > or_s(self.selStack);
0108 UnaryCutSetter<logical_not<bool> > not_s(self.selStack);
0109 CutSetter cut_s(*self.sel_, self.selStack);
0110 ExpressionSetter expr_s(*self.expr_, self.exprStack);
0111 ExpressionBinaryOperatorSetter<plus<double> > plus_s(self.exprStack);
0112 ExpressionBinaryOperatorSetter<minus<double> > minus_s(self.exprStack);
0113 ExpressionBinaryOperatorSetter<multiplies<double> > multiplies_s(self.exprStack);
0114 ExpressionBinaryOperatorSetter<divides<double> > divides_s(self.exprStack);
0115 ExpressionBinaryOperatorSetter<int_div_remainder<double> > remainder_s(self.exprStack);
0116 ExpressionBinaryOperatorSetter<power_of<double> > power_of_s(self.exprStack);
0117 ExpressionUnaryOperatorSetter<negate<double> > negate_s(self.exprStack);
0118 ExpressionFunctionSetter fun_s(self.exprStack, self.finalFunStack);
0119
0120 BOOST_SPIRIT_DEBUG_RULE(var);
0121 BOOST_SPIRIT_DEBUG_RULE(arrayAccess);
0122 BOOST_SPIRIT_DEBUG_RULE(method);
0123 BOOST_SPIRIT_DEBUG_RULE(logical_expression);
0124 BOOST_SPIRIT_DEBUG_RULE(cond_expression);
0125 BOOST_SPIRIT_DEBUG_RULE(logical_term);
0126 BOOST_SPIRIT_DEBUG_RULE(logical_factor);
0127 BOOST_SPIRIT_DEBUG_RULE(number);
0128 BOOST_SPIRIT_DEBUG_RULE(metharg);
0129 BOOST_SPIRIT_DEBUG_RULE(function1);
0130 BOOST_SPIRIT_DEBUG_RULE(function2);
0131 BOOST_SPIRIT_DEBUG_RULE(function4);
0132 BOOST_SPIRIT_DEBUG_RULE(expression);
0133 BOOST_SPIRIT_DEBUG_RULE(term);
0134 BOOST_SPIRIT_DEBUG_RULE(power);
0135 BOOST_SPIRIT_DEBUG_RULE(factor);
0136 BOOST_SPIRIT_DEBUG_RULE(or_op);
0137 BOOST_SPIRIT_DEBUG_RULE(and_op);
0138 BOOST_SPIRIT_DEBUG_RULE(comparison_op);
0139 BOOST_SPIRIT_DEBUG_RULE(binary_comp);
0140 BOOST_SPIRIT_DEBUG_RULE(trinary_comp);
0141 BOOST_SPIRIT_DEBUG_RULE(cut);
0142 BOOST_SPIRIT_DEBUG_RULE(fun);
0143
0144 boost::spirit::classic::assertion<SyntaxErrors> expectParenthesis(kMissingClosingParenthesis);
0145 boost::spirit::classic::assertion<SyntaxErrors> expect(kSyntaxError);
0146
0147 number = real_p[number_s];
0148 metharg = (strict_real_p[methodArg_s]) | (int_p[methodArg_s]) |
0149 (ch_p('"') >> *(~ch_p('"')) >> ch_p('"'))[methodArg_s] |
0150 (ch_p('\'') >> *(~ch_p('\'')) >> ch_p('\''))[methodArg_s];
0151 var =
0152 (lexeme_d[alpha_p >> *chset<>("a-zA-Z0-9_")] >> ch_p('(') >> metharg >> *(ch_p(',') >> metharg) >>
0153 expectParenthesis(ch_p(')')))[method_s] |
0154 ((lexeme_d[alpha_p >> *chset<>("a-zA-Z0-9_")])[method_s] >> !(ch_p('(') >> ch_p(')')));
0155 arrayAccess = (ch_p('[') >> metharg >> *(ch_p(',') >> metharg) >> expectParenthesis(ch_p(']')))[method_s];
0156 method = (var >> *(arrayAccess | (ch_p('.') >> expect(var))))[var_s];
0157 function1 = chseq_p("abs")[abs_s] | chseq_p("acos")[acos_s] | chseq_p("asin")[asin_s] |
0158 chseq_p("atan")[atan_s] | chseq_p("cosh")[cosh_s] | chseq_p("cos")[cos_s] |
0159 chseq_p("exp")[exp_s] | chseq_p("log")[log_s] | chseq_p("log10")[log10_s] |
0160 chseq_p("sinh")[sinh_s] | chseq_p("sin")[sin_s] | chseq_p("sqrt")[sqrt_s] |
0161 chseq_p("tanh")[tanh_s] | chseq_p("tan")[tan_s];
0162 function2 = chseq_p("atan2")[atan2_s] | chseq_p("chi2prob")[chi2prob_s] | chseq_p("pow")[pow_s] |
0163 chseq_p("min")[min_s] | chseq_p("max")[max_s] | chseq_p("deltaPhi")[deltaPhi_s] |
0164 chseq_p("hypot")[hypot_s] | chseq_p("test_bit")[test_bit_s];
0165 function4 = chseq_p("deltaR")[deltaR_s];
0166 expression = cond_expression | nocond_expression;
0167 nocond_expression = term >> (*(('+' >> expect(term))[plus_s] | ('-' >> expect(term))[minus_s]));
0168 cond_expression = (ch_p('?') >> logical_expression >> ch_p('?') >> expect(expression) >> ch_p(":") >>
0169 expect(expression))[cond_s];
0170 term = power >> *(('*' >> expect(power))[multiplies_s] | ('/' >> expect(power))[divides_s] |
0171 ('%' >> expect(power))[remainder_s]);
0172 power = factor >> *(('^' >> expect(factor))[power_of_s]);
0173 factor =
0174 number | (function1 >> ch_p('(')[funOk_s] >> expect(expression) >> expectParenthesis(ch_p(')')))[fun_s] |
0175 (function2 >> ch_p('(')[funOk_s] >> expect(expression) >> expect(ch_p(',')) >> expect(expression) >>
0176 expectParenthesis(ch_p(')')))[fun_s] |
0177 (function4 >> ch_p('(')[funOk_s] >> expect(expression) >> expect(ch_p(',')) >> expect(expression) >>
0178 expect(ch_p(',')) >> expect(expression) >> expect(ch_p(',')) >> expect(expression) >>
0179 expectParenthesis(ch_p(')')))[fun_s] |
0180
0181 method |
0182
0183
0184
0185
0186
0187
0188
0189 ch_p('(') >> expression >> ch_p(')') | (ch_p('-') >> factor)[negate_s] | (ch_p('+') >> factor);
0190 comparison_op = (ch_p('<') >> ch_p('=')[less_equal_s]) | (ch_p('<')[less_s]) |
0191 (ch_p('=') >> ch_p('=')[equal_to_s]) | (ch_p('=')[equal_to_s]) |
0192 (ch_p('>') >> ch_p('=')[greater_equal_s]) | (ch_p('>')[greater_s]) |
0193 (ch_p('!') >> ch_p('=')[not_equal_to_s]);
0194 binary_comp = (expression >> comparison_op >> expect(expression))[binary_s];
0195 trinary_comp =
0196 (expression >> comparison_op >> expect(expression) >> comparison_op >> expect(expression))[trinary_s];
0197 or_op = ch_p('|') >> ch_p('|') | ch_p('|');
0198 and_op = ch_p('&') >> ch_p('&') | ch_p('&');
0199 logical_expression = logical_term >> *(or_op >> expect(logical_term))[or_s];
0200 logical_term = logical_factor >> *(and_op >> expect(logical_factor))[and_s];
0201 logical_factor = trinary_comp | binary_comp |
0202 ch_p('(') >> logical_expression >> expectParenthesis(ch_p(')')) |
0203 (ch_p('!') >> expect(logical_factor))[not_s] | expression[expr_sel_s];
0204 ;
0205 cut = logical_expression[cut_s];
0206 fun = expression[expr_s];
0207 this->start_parsers(cut, fun);
0208 }
0209 };
0210 };
0211 }
0212 }
0213
0214 #endif