CMS 3D CMS Logo

Grammar.h

Go to the documentation of this file.
00001 #ifndef Utilities_Grammar_h
00002 #define Utilities_Grammar_h
00003 /* \class reco::parser::Grammar
00004  *
00005  * parser grammar
00006  *
00007  * \author original version: Chris Jones, Cornell, 
00008  *         extended by Luca Lista, INFN
00009  *
00010  * \version $Revision: 1.19.2.1 $
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 // #include "PhysicsTools/Utilities/src/Abort.h"
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           //      Abort abort_s;
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             //NOTE: no expect around the first ch_p('(') otherwise it can't parse a method that starts like a function name (i.e. maxSomething)
00186             method | 
00187             //NOTE: no 'expectedParenthesis around ending ')' because at this point the partial phrase
00188             //       "(a"
00189             //could refer to an expression, e.g., "(a+b)*c" or a logical expression "(a<1) &&"
00190             //so we need to allow the parser to 'backup' and try a different approach.
00191             //NOTE: if the parser were changed so a logical expression could be used as an expression,e.g.
00192             //  (a<b)+1 <2
00193             // then we could remove such an ambiguity.
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

Generated on Tue Jun 9 17:42:52 2009 for CMSSW by  doxygen 1.5.4