Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-09 23:33:15

0001 #ifndef CommonTools_Utils_MethodChainGrammar_h
0002 #define CommonTools_Utils_MethodChainGrammar_h
0003 /* \class MethodChainGrammer
0004  *
0005  * subset grammar of the full Grammer (CommonTools/Utils/interface/parser/Grammar.h), allowing only a chain of methods 
0006  *
0007  */
0008 
0009 #include "boost/spirit/include/classic_core.hpp"
0010 #include "boost/spirit/include/classic_grammar_def.hpp"
0011 #include "boost/spirit/include/classic_chset.hpp"
0012 #include "FWCore/Utilities/interface/EDMException.h"
0013 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0014 #include "CommonTools/Utils/interface/parser/MethodChain.h"
0015 #include "CommonTools/Utils/interface/parser/MethodChainSetter.h"
0016 #include "CommonTools/Utils/interface/parser/MethodSetter.h"
0017 #include "CommonTools/Utils/interface/parser/MethodArgumentSetter.h"
0018 #include "CommonTools/Utils/interface/parser/MethodInvoker.h"
0019 #include "CommonTools/Utils/interface/parser/MethodStack.h"
0020 #include "CommonTools/Utils/interface/parser/TypeStack.h"
0021 #include "CommonTools/Utils/interface/parser/MethodArgumentStack.h"
0022 #include "CommonTools/Utils/interface/parser/AnyMethodArgument.h"
0023 #include "CommonTools/Utils/interface/parser/Exception.h"
0024 
0025 namespace reco {
0026   namespace parser {
0027     struct MethodChainGrammar : public boost::spirit::classic::grammar<MethodChainGrammar> {
0028       MethodChainPtr* methchain_;
0029       bool lazy_;
0030       mutable MethodStack methStack;
0031       mutable LazyMethodStack lazyMethStack;
0032       mutable MethodArgumentStack methArgStack;
0033       mutable TypeStack typeStack;
0034 
0035       MethodChainGrammar(MethodChainPtr& methchain, const edm::TypeWithDict& iType, bool lazy = false)
0036           : methchain_(&methchain), lazy_(lazy) {
0037         typeStack.push_back(iType);
0038       }
0039 
0040       template <typename ScannerT>
0041       struct definition {
0042         typedef boost::spirit::classic::rule<ScannerT> rule;
0043         rule metharg, method, arrayAccess, methodchain;
0044         definition(const MethodChainGrammar& self) {
0045           using namespace boost::spirit::classic;
0046 
0047           MethodArgumentSetter methodArg_s(self.methArgStack);
0048           MethodSetter method_s(self.methStack, self.lazyMethStack, self.typeStack, self.methArgStack, self.lazy_);
0049           MethodChainSetter methodchain_s(*self.methchain_, self.methStack, self.lazyMethStack, self.typeStack);
0050 
0051           BOOST_SPIRIT_DEBUG_RULE(methodchain);
0052           BOOST_SPIRIT_DEBUG_RULE(arrayAccess);
0053           BOOST_SPIRIT_DEBUG_RULE(method);
0054           BOOST_SPIRIT_DEBUG_RULE(metharg);
0055 
0056           boost::spirit::classic::assertion<SyntaxErrors> expectParenthesis(kMissingClosingParenthesis);
0057           boost::spirit::classic::assertion<SyntaxErrors> expect(kSyntaxError);
0058 
0059           metharg = (strict_real_p[methodArg_s]) | (int_p[methodArg_s]) |
0060                     (ch_p('"') >> *(~ch_p('"')) >> ch_p('"'))[methodArg_s] |
0061                     (ch_p('\'') >> *(~ch_p('\'')) >> ch_p('\''))[methodArg_s];
0062           method =  // alnum_p doesn't accept underscores, so we use chset<>; lexeme_d needed to avoid whitespace skipping within method names
0063               (lexeme_d[alpha_p >> *chset<>("a-zA-Z0-9_")] >> ch_p('(') >> metharg >> *(ch_p(',') >> metharg) >>
0064                expectParenthesis(ch_p(')')))[method_s] |
0065               ((lexeme_d[alpha_p >> *chset<>("a-zA-Z0-9_")])[method_s] >> !(ch_p('(') >> ch_p(')')));
0066           arrayAccess = (ch_p('[') >> metharg >> *(ch_p(',') >> metharg) >> expectParenthesis(ch_p(']')))[method_s];
0067           methodchain = (method >> *(arrayAccess | (ch_p('.') >> expect(method))))[methodchain_s];
0068         }
0069 
0070         rule const& start() const { return methodchain; }
0071       };
0072     };
0073   }  // namespace parser
0074 }  // namespace reco
0075 
0076 #endif