#include #include //Class hierarchy into which we would like to parse the data class testnode { public: testnode(){}; testnode(testnode* pChild){m_pChildren.push_back(pChild);}; protected: std::vector m_pChildren; }; class testnodetext : public testnode { public: testnodetext(std::string sVal){m_sVal=sVal;}; private: std::string m_sVal; }; class testnodeor : public testnode { public: testnodeor(testnode* pL,testnode* pR){m_pChildren.push_back(pL);m_pChildren.push_back(pR);} }; class testnodeand : public testnode { public: testnodeand(testnode* pL,testnode* pR){m_pChildren.push_back(pL);m_pChildren.push_back(pR);} }; class testnodenot : public testnode { public: testnodenot(testnode* pNot){m_pChildren.push_back(pNot);}; }; //Boiler plate base class that does most of the 'work' creating the parse tree //This is somewhat 'equivalent' to the grammar class of spirit //We can re-use this base for every pointer based grammar we would like to create template class XpressiveGrammarBase { public: protected: //Functions to allow us to create new nodes as needed template struct mknode_impl { mknode_impl(std::deque* paStack): m_paStack(paStack){}; typedef void result_type; void operator()() const { m_paStack->push_back(new Tmk()); } template void operator()(Value1 const &val1) const { m_paStack->push_back(new Tmk(val1)); } template void operator()(Value1 const &val1,Value2 const &val2) const { m_paStack->push_back(new Tmk(val1,val2)); } std::deque* m_paStack; }; template typename boost::xpressive::detail::make_function::impl const>::result_type const mknode_() { return boost::xpressive::detail::make_function::impl const>()((mknode_impl(&m_aStack))); } template typename boost::xpressive::detail::make_function::impl const, A0 const &>::result_type const mknode_(A0 const &a0) { return boost::xpressive::detail::make_function::impl const, A0 const &>()((mknode_impl(&m_aStack)), a0); } template typename boost::xpressive::detail::make_function::impl const, A0 const &, A1 const &>::result_type const mknode_(A0 const &a0,A1 const &a1) { return boost::xpressive::detail::make_function::impl const, A0 const &, A1 const &>()((mknode_impl(&m_aStack)), a0, a1); } //Function to retrieve previously created child nodes (so that we can create composite nodes etc.) struct getnode_impl { getnode_impl(std::deque* paStack): m_paStack(paStack){}; typedef TBase* result_type; TBase* operator()() const { TBase* pRet = m_paStack->front(); m_paStack->pop_front(); return pRet; } std::deque* m_paStack; }; typename boost::xpressive::detail::make_function::impl::result_type const getnode_() { return boost::xpressive::detail::make_function::impl()((getnode_impl(&m_aStack))); } private: std::deque m_aStack; }; //Example of an actual grammar class testgrammar: public XpressiveGrammarBase { public: testgrammar(std::string sSearch,testnode*& pRoot) { using namespace boost::xpressive; rulestart = bos >> by_ref(rulenode) >> eos [ref(pRoot)=getnode_()];; rulenode = (by_ref(ruletextnode)|by_ref(rulenotnode)|by_ref(ruleandnode)|by_ref(ruleornode)); ruletextnode = (s1 = +(~(set='!','&','|'))) [mknode_(s1)]; rulenotnode = '!' >> by_ref(rulenode) [mknode_(getnode_())]; ruleandnode = (by_ref(ruletextnode)|by_ref(rulenotnode)|by_ref(ruleornode)) >> '&' >> by_ref(rulenode) [mknode_(getnode_(),getnode_())]; ruleornode = (by_ref(ruletextnode)|by_ref(rulenotnode)) >> '|' >> by_ref(rulenode) [mknode_(getnode_(),getnode_())]; regex_search(sSearch,rulestart); } protected: private: boost::xpressive::sregex rulestart, rulenode, rulenotnode, ruleornode, ruleandnode, ruletextnode; }; int main(int argc, char *argv[]) { std::string sTest = "abcd|!xyz|qwerty"; testnode* pRoot=NULL; testgrammar grammar(sTest,pRoot); if(pRoot) { //Success //->testnodeor // -> testnodetext ("abcd") // ->testnodeor // ->testnodenot // ->testnodetext("xyz") // ->testnodetext ("qwerty") } else { //Failed } return 0; }