File indexing completed on 2023-10-25 09:53:01
0001 #ifndef HLTrigger_HLTcore_TriggerExpressionParser_h
0002 #define HLTrigger_HLTcore_TriggerExpressionParser_h
0003
0004
0005 #include <boost/phoenix.hpp>
0006 #include <boost/spirit/include/qi.hpp>
0007
0008 #include "HLTrigger/HLTcore/interface/TriggerExpressionPathReader.h"
0009 #include "HLTrigger/HLTcore/interface/TriggerExpressionL1uGTReader.h"
0010 #include "HLTrigger/HLTcore/interface/TriggerExpressionOperators.h"
0011 #include "HLTrigger/HLTcore/interface/TriggerExpressionPrescaler.h"
0012 #include "HLTrigger/HLTcore/interface/TriggerExpressionConstant.h"
0013
0014 namespace triggerExpression {
0015
0016 namespace qi = boost::spirit::qi;
0017 namespace ascii = boost::spirit::ascii;
0018
0019 using boost::phoenix::new_;
0020 using boost::spirit::unused_type;
0021
0022 template <typename Iterator>
0023 class Parser : public qi::grammar<Iterator, Evaluator *(), ascii::space_type> {
0024 public:
0025 Parser() : Parser::base_type(expression) {
0026 auto delimiter = qi::copy(qi::eoi | !qi::char_("a-zA-Z0-9_*?"));
0027
0028 operand_not = qi::lexeme[qi::lit("NOT") >> delimiter];
0029 operand_and = qi::lexeme[qi::lit("AND") >> delimiter];
0030 operand_or = qi::lexeme[qi::lit("OR") >> delimiter];
0031 operand_xor = qi::lexeme[qi::lit("XOR") >> delimiter];
0032 operand_masking = qi::lexeme[qi::lit("MASKING") >> delimiter];
0033
0034
0035 token_true = qi::lexeme[qi::lit("TRUE") >> delimiter];
0036
0037
0038 token_false = qi::lexeme[qi::lit("FALSE") >> delimiter];
0039
0040
0041 token_l1algo %= qi::raw[qi::lexeme["L1_" >> +(qi::char_("a-zA-Z0-9_*?"))]];
0042
0043
0044
0045 token_path %= qi::raw[qi::lexeme[+(qi::char_("a-zA-Z0-9_*?"))] - token_true - token_false - operand_not -
0046 operand_and - operand_or - operand_xor - operand_masking];
0047
0048 token = (token_true[qi::_val = new_<Constant>(true)] | token_false[qi::_val = new_<Constant>(false)] |
0049 token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] | token_path[qi::_val = new_<PathReader>(qi::_1)]);
0050
0051 parenthesis %= ('(' >> expression >> ')');
0052
0053 element %= (token | parenthesis);
0054
0055 prescale = (element >> '/' >> qi::uint_)[qi::_val = new_<Prescaler>(qi::_1, qi::_2)];
0056
0057 operand %= (prescale | element);
0058
0059 unary = ((operand_not >> unary)[qi::_val = new_<OperatorNot>(qi::_1)] | operand[qi::_val = qi::_1]);
0060
0061
0062
0063 token_masking =
0064 (token_false[qi::_val = new_<Constant>(false)] | token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] |
0065 token_path[qi::_val = new_<PathReader>(qi::_1)]);
0066
0067 argument_masking %= (token_masking | ('(' >> argument_masking >> ')'));
0068
0069 expression = unary[qi::_val = qi::_1] >>
0070 *((operand_and >> unary)[qi::_val = new_<OperatorAnd>(qi::_val, qi::_1)] |
0071 (operand_or >> unary)[qi::_val = new_<OperatorOr>(qi::_val, qi::_1)] |
0072 (operand_xor >> unary)[qi::_val = new_<OperatorXor>(qi::_val, qi::_1)] |
0073 (operand_masking >> argument_masking)[qi::_val = new_<OperatorMasking>(qi::_val, qi::_1)]);
0074 }
0075
0076 private:
0077 typedef qi::rule<Iterator, std::string(), ascii::space_type> name_rule;
0078 typedef qi::rule<Iterator, Evaluator *(), ascii::space_type> rule;
0079 typedef qi::rule<Iterator> terminal_rule;
0080
0081 terminal_rule token_true;
0082 terminal_rule token_false;
0083
0084 terminal_rule operand_not;
0085 terminal_rule operand_and;
0086 terminal_rule operand_or;
0087 terminal_rule operand_xor;
0088 terminal_rule operand_masking;
0089
0090 name_rule token_l1algo;
0091 name_rule token_path;
0092
0093 rule token;
0094 rule parenthesis;
0095 rule element;
0096 rule prescale;
0097 rule operand;
0098 rule unary;
0099 rule token_masking;
0100 rule argument_masking;
0101 rule expression;
0102 };
0103
0104
0105 template <class T>
0106 Evaluator *parse(const T &text) {
0107 typedef typename T::const_iterator Iterator;
0108 Parser<Iterator> parser;
0109 Evaluator *evaluator = nullptr;
0110
0111 Iterator begin = text.begin();
0112 Iterator end = text.end();
0113
0114
0115 bool result = qi::phrase_parse(begin, end, parser, ascii::space, evaluator);
0116
0117 if (not result or begin != end) {
0118 delete evaluator;
0119 return nullptr;
0120 }
0121
0122 return evaluator;
0123 }
0124
0125
0126 inline Evaluator *parse(const char *text) {
0127 Parser<const char *> parser;
0128 Evaluator *evaluator = nullptr;
0129
0130 const char *begin = text;
0131 const char *end = text + strlen(text);
0132
0133
0134 bool result = qi::phrase_parse(begin, end, parser, ascii::space, evaluator);
0135
0136 if (not result or begin != end) {
0137 delete evaluator;
0138 return nullptr;
0139 }
0140
0141 return evaluator;
0142 }
0143
0144 }
0145
0146 #endif