CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Grammar.h
Go to the documentation of this file.
1 #ifndef CommonTools_Utils_Grammar_h
2 #define CommonTools_Utils_Grammar_h
3 /* \class reco::parser::Grammar
4  *
5  * parser grammar
6  *
7  * \author original version: Chris Jones, Cornell,
8  * extended by Luca Lista, INFN
9  *
10  * \version $Revision: 1.12 $
11  *
12  */
13 #include "boost/spirit/include/classic_core.hpp"
14 #include "boost/spirit/include/classic_grammar_def.hpp"
15 #include "boost/spirit/include/classic_chset.hpp"
16 #include <functional>
40 // #include "CommonTools/Utils/src/Abort.h"
41 
42 namespace reco {
43  namespace parser {
44  struct Grammar : public boost::spirit::classic::grammar<Grammar> {
45 
50  bool lazy_;
59  mutable IntStack intStack;
60 
61  Grammar(SelectorPtr & sel, const Reflex::Type& iType, bool lazy=false) :
62  sel_(& sel), expr_(& dummyExpr_), lazy_(lazy) {
63  typeStack.push_back(iType);
64  }
65 
66  Grammar(ExpressionPtr & expr, const Reflex::Type& iType, bool lazy=false) :
67  sel_(& dummySel_), expr_(& expr), lazy_(lazy) {
68  typeStack.push_back(iType);
69  }
70  template <typename ScannerT>
71  struct definition :
72  public boost::spirit::classic::grammar_def<boost::spirit::classic::rule<ScannerT>,
73  boost::spirit::classic::same,
74  boost::spirit::classic::same>{
75  typedef boost::spirit::classic::rule<ScannerT> rule;
79  or_op, and_op, cut, fun;
80  definition(const Grammar & self) {
81  using namespace boost::spirit::classic;
82  using namespace std;
83 
84  ExpressionNumberSetter number_s(self.exprStack);
85  IntSetter int_s(self.intStack);
86  ExpressionVarSetter var_s(self.exprStack, self.methStack, self.lazyMethStack, self.typeStack);
87  ExpressionConditionSetter cond_s(self.exprStack, self.selStack);
88  MethodArgumentSetter methodArg_s(self.methArgStack);
89  MethodSetter method_s(self.methStack, self.lazyMethStack, self.typeStack, self.methArgStack, self.lazy_);
90  ComparisonSetter<less_equal<double> > less_equal_s(self.cmpStack);
93  ComparisonSetter<greater_equal<double> > greater_equal_s(self.cmpStack);
95  ComparisonSetter<not_equal_to<double> > not_equal_to_s(self.cmpStack);
97  abs_s(kAbs, self.funStack), acos_s(kAcos, self.funStack), asin_s(kAsin, self.funStack),
98  atan2_s(kAtan, self.funStack), atan_s(kAtan, self.funStack),
99  chi2prob_s(kChi2Prob, self.funStack),
100  cosh_s(kCosh, self.funStack),
101  cos_s(kCos, self.funStack), exp_s(kExp, self.funStack), hypot_s(kHypot, self.funStack), log_s(kLog, self.funStack),
102  log10_s(kLog10, self.funStack), max_s(kMax, self.funStack), min_s(kMin, self.funStack),
103  pow_s(kPow, self.funStack), sinh_s(kSinh, self.funStack),
104  sin_s(kSin, self.funStack), sqrt_s(kSqrt, self.funStack), tanh_s(kTanh, self.funStack),
105  tan_s(kTan, self.funStack),
106  deltaPhi_s(kDeltaPhi, self.funStack), deltaR_s(kDeltaR, self.funStack),
107  test_bit_s(kTestBit, self.funStack);
108  FunctionSetterCommit funOk_s(self.funStack, self.finalFunStack);
109  TrinarySelectorSetter trinary_s(self.selStack, self.cmpStack, self.exprStack);
110  BinarySelectorSetter binary_s(self.selStack, self.cmpStack, self.exprStack);
111  ExpressionSelectorSetter expr_sel_s(self.selStack, self.exprStack);
115  CutSetter cut_s(* self.sel_, self.selStack);
116  ExpressionSetter expr_s(* self.expr_, self.exprStack);
124  // Abort abort_s;
125  BOOST_SPIRIT_DEBUG_RULE(var);
126  BOOST_SPIRIT_DEBUG_RULE(arrayAccess);
127  BOOST_SPIRIT_DEBUG_RULE(method);
128  BOOST_SPIRIT_DEBUG_RULE(logical_expression);
129  BOOST_SPIRIT_DEBUG_RULE(cond_expression);
130  BOOST_SPIRIT_DEBUG_RULE(logical_term);
131  BOOST_SPIRIT_DEBUG_RULE(logical_factor);
132  BOOST_SPIRIT_DEBUG_RULE(number);
133  BOOST_SPIRIT_DEBUG_RULE(metharg);
134  BOOST_SPIRIT_DEBUG_RULE(function1);
135  BOOST_SPIRIT_DEBUG_RULE(function2);
136  BOOST_SPIRIT_DEBUG_RULE(function4);
137  BOOST_SPIRIT_DEBUG_RULE(expression);
138  BOOST_SPIRIT_DEBUG_RULE(term);
139  BOOST_SPIRIT_DEBUG_RULE(power);
140  BOOST_SPIRIT_DEBUG_RULE(factor);
141  BOOST_SPIRIT_DEBUG_RULE(or_op);
142  BOOST_SPIRIT_DEBUG_RULE(and_op);
143  BOOST_SPIRIT_DEBUG_RULE(comparison_op);
144  BOOST_SPIRIT_DEBUG_RULE(binary_comp);
145  BOOST_SPIRIT_DEBUG_RULE(trinary_comp);
146  BOOST_SPIRIT_DEBUG_RULE(cut);
147  BOOST_SPIRIT_DEBUG_RULE(fun);
148 
149  boost::spirit::classic::assertion<SyntaxErrors> expectParenthesis(kMissingClosingParenthesis);
150  boost::spirit::classic::assertion<SyntaxErrors> expect(kSyntaxError);
151 
152  number =
153  real_p [ number_s ];
154  metharg = ( strict_real_p [ methodArg_s ] ) |
155  ( int_p [ methodArg_s ] ) |
156  ( ch_p('"' ) >> *(~ch_p('"' )) >> ch_p('"' ) ) [ methodArg_s ] |
157  ( ch_p('\'') >> *(~ch_p('\'')) >> ch_p('\'') ) [ methodArg_s ];
158  var = // alnum_p doesn't accept underscores, so we use chset<>; lexeme_d needed to avoid whitespace skipping within method names
159  (lexeme_d[alpha_p >> * chset<>("a-zA-Z0-9_")] >>
160  ch_p('(') >> metharg >> * (ch_p(',') >> metharg ) >> expectParenthesis(ch_p(')'))) [ method_s ] |
161  ( (lexeme_d[alpha_p >> * chset<>("a-zA-Z0-9_")]) [ method_s ] >> ! (ch_p('(') >> ch_p(')')) ) ;
162  arrayAccess = ( ch_p('[') >> metharg >> * (ch_p(',') >> metharg ) >> expectParenthesis(ch_p(']'))) [ method_s ];
163  method =
164  (var >> * (arrayAccess | (ch_p('.') >> expect(var)))) [ var_s ];
165  function1 =
166  chseq_p("abs") [ abs_s ] | chseq_p("acos") [ acos_s ] | chseq_p("asin") [ asin_s ] |
167  chseq_p("atan") [ atan_s ] | chseq_p("cosh") [ cosh_s ] | chseq_p("cos") [ cos_s ] |
168  chseq_p("exp") [ exp_s ] | chseq_p("log") [ log_s ] | chseq_p("log10") [ log10_s ] |
169  chseq_p("sinh") [ sinh_s ] | chseq_p("sin") [ sin_s ] | chseq_p("sqrt") [ sqrt_s ] |
170  chseq_p("tanh") [ tanh_s ] | chseq_p("tan") [ tan_s ];
171  function2 =
172  chseq_p("atan2") [ atan2_s ] | chseq_p("chi2prob") [ chi2prob_s ] | chseq_p("pow") [ pow_s ] |
173  chseq_p("min") [ min_s ] | chseq_p("max") [ max_s ] | chseq_p("deltaPhi") [deltaPhi_s] | chseq_p("hypot") [hypot_s] | chseq_p("test_bit") [test_bit_s] ;
174  function4 =
175  chseq_p("deltaR") [deltaR_s];
176  expression =
180  term >> (* (('+' >> expect(term)) [ plus_s ] |
181  ('-' >> expect(term)) [ minus_s ]));
182  cond_expression =
183  (ch_p('?') >> logical_expression >> ch_p('?') >> expect(expression) >> ch_p(":") >> expect(expression)) [cond_s];
184  term =
185  power >> * (('*' >> expect(power)) [ multiplies_s ] |
186  ('/' >> expect(power)) [ divides_s ]);
187  power =
188  factor >> * (('^' >> expect(factor)) [ power_of_s ]);
189  factor =
190  number |
191  (function1 >> ch_p('(') [funOk_s ] >> expect(expression) >> expectParenthesis(ch_p(')'))) [ fun_s ] |
192  (function2 >> ch_p('(') [funOk_s ] >> expect(expression) >>
193  expect(ch_p(',')) >> expect(expression) >> expectParenthesis(ch_p(')'))) [ fun_s ] |
194  (function4 >> ch_p('(') [funOk_s ] >> expect(expression) >> expect(ch_p(',')) >> expect(expression) >> expect(ch_p(',')) >> expect(expression) >>
195  expect(ch_p(',')) >> expect(expression) >> expectParenthesis(ch_p(')'))) [ fun_s ] |
196  //NOTE: no expect around the first ch_p('(') otherwise it can't parse a method that starts like a function name (i.e. maxSomething)
197  method |
198  //NOTE: no 'expectedParenthesis around ending ')' because at this point the partial phrase
199  // "(a"
200  //could refer to an expression, e.g., "(a+b)*c" or a logical expression "(a<1) &&"
201  //so we need to allow the parser to 'backup' and try a different approach.
202  //NOTE: if the parser were changed so a logical expression could be used as an expression,e.g.
203  // (a<b)+1 <2
204  // then we could remove such an ambiguity.
205  ch_p('(') >> expression >> ch_p(')') |
206  (ch_p('-') >> factor) [ negate_s ] |
207  (ch_p('+') >> factor);
208  comparison_op =
209  (ch_p('<') >> ch_p('=') [ less_equal_s ]) |
210  (ch_p('<') [ less_s ]) |
211  (ch_p('=') >> ch_p('=') [ equal_to_s ]) |
212  (ch_p('=') [ equal_to_s ]) |
213  (ch_p('>') >> ch_p('=') [ greater_equal_s ]) |
214  (ch_p('>') [ greater_s ]) |
215  (ch_p('!') >> ch_p('=') [ not_equal_to_s ]);
216  binary_comp =
217  (expression >> comparison_op >> expect(expression)) [ binary_s ];
218  trinary_comp =
219  (expression >> comparison_op >> expect(expression) >> comparison_op >> expect(expression)) [ trinary_s ];
220  or_op = ch_p('|') >> ch_p('|') | ch_p('|');
221  and_op = ch_p('&') >> ch_p('&') | ch_p('&');
223  logical_term >> * (or_op >> expect(logical_term)) [ or_s ];
224  logical_term =
225  logical_factor >> * (and_op >> expect(logical_factor)) [ and_s ];
227  trinary_comp |
228  binary_comp |
229  ch_p('(') >> logical_expression >> expectParenthesis(ch_p(')')) |
230  (ch_p('!') >> expect(logical_factor)) [ not_s ] |
231  expression [ expr_sel_s ];
232 ;
233  cut = logical_expression [ cut_s ];
234  fun = expression [ expr_s ];
235  this->start_parsers(cut, fun);
236  }
237  };
238  };
239  }
240 }
241 
242 
243 #endif
FunctionStack funStack
Definition: Grammar.h:54
Grammar(ExpressionPtr &expr, const Reflex::Type &iType, bool lazy=false)
Definition: Grammar.h:66
ComparisonStack cmpStack
Definition: Grammar.h:52
LazyMethodStack lazyMethStack
Definition: Grammar.h:56
FunctionStack finalFunStack
Definition: Grammar.h:54
boost::shared_ptr< ExpressionBase > ExpressionPtr
std::vector< AnyMethodArgument > MethodArgumentStack
boost::spirit::classic::rule< ScannerT > rule
Definition: Grammar.h:75
std::vector< boost::shared_ptr< ExpressionBase > > ExpressionStack
std::vector< SelectorPtr > SelectorStack
Definition: SelectorStack.h:18
ExpressionPtr * expr_
Definition: Grammar.h:49
std::vector< LazyInvoker > LazyMethodStack
Definition: MethodStack.h:18
std::vector< int > IntStack
Definition: IntStack.h:16
SelectorStack selStack
Definition: Grammar.h:53
IntStack intStack
Definition: Grammar.h:59
boost::shared_ptr< SelectorBase > SelectorPtr
Definition: SelectorPtr.h:17
SelectorPtr * sel_
Definition: Grammar.h:48
MethodArgumentStack methArgStack
Definition: Grammar.h:57
definition(const Grammar &self)
Definition: Grammar.h:80
SelectorPtr dummySel_
Definition: Grammar.h:46
ExpressionPtr dummyExpr_
Definition: Grammar.h:47
std::vector< MethodInvoker > MethodStack
Definition: MethodStack.h:17
ExpressionStack exprStack
Definition: Grammar.h:51
MethodStack methStack
Definition: Grammar.h:55
Grammar(SelectorPtr &sel, const Reflex::Type &iType, bool lazy=false)
Definition: Grammar.h:61
std::vector< boost::shared_ptr< ComparisonBase > > ComparisonStack
std::vector< Function > FunctionStack
Definition: FunctionStack.h:17
TypeStack typeStack
Definition: Grammar.h:58
std::vector< Reflex::Type > TypeStack
Definition: TypeStack.h:17