#include "belr/parser.hh" #include #include //#include #include namespace belr{ template T universal_pointer_cast(const shared_ptr& sp){ return static_pointer_cast(sp); } template T universal_pointer_cast(U * p){ return static_cast(p); } template AbstractCollector<_parserElementT>::~AbstractCollector(){ } template void ParserCollector<_derivedParserElementT,_parserElementT, _valueT>::invoke(_parserElementT obj, _valueT value){ mFunc(universal_pointer_cast<_derivedParserElementT>(obj),value); } template void ParserCollector<_derivedParserElementT,_parserElementT, _valueT>::invokeWithChild(_parserElementT obj, _parserElementT child){ cerr<<"We should never be called in ParserCollector<_derivedParserElementT,_parserElementT, _valueT>::invokeWithChild(_parserElementT obj, _parserElementT child)"< void ParserChildCollector<_derivedParserElementT,_parserElementT, _valueT>::invokeWithChild(_parserElementT obj, _parserElementT value){ mFunc(universal_pointer_cast<_derivedParserElementT>(obj),universal_pointer_cast::type>(value)); } template void ParserChildCollector<_derivedParserElementT,_parserElementT, _valueT>::invoke(_parserElementT obj, _valueT value){ cerr<<"We should never be called in ParserChildCollector<_derivedParserElementT,_parserElementT, _valueT>::invoke(_parserElementT obj, _valueT value)"< void Assignment<_parserElementT>::invoke(_parserElementT parent, const string &input){ if (mChild){ mCollector->invokeWithChild(parent, mChild->realize(input,mBegin,mCount)); }else{ string value=input.substr(mBegin, mCount); CollectorBase<_parserElementT,const string&>* cc1=dynamic_cast*>(mCollector); if (cc1){ cc1->invoke(parent, value); return; } CollectorBase<_parserElementT,const char*>* cc2=dynamic_cast*>(mCollector); if (cc2){ cc2->invoke(parent, value.c_str()); return; } CollectorBase<_parserElementT,int> *cc3=dynamic_cast*>(mCollector); if (cc3){ cc3->invoke(parent, atoi(value.c_str())); return; } } } // // HandlerContext template class implementation // template HandlerContext<_parserElementT>::HandlerContext(const shared_ptr> &handler) : mHandler(*handler.get()){ } template void HandlerContext<_parserElementT>::setChild(unsigned int subrule_id, size_t begin, size_t count, const shared_ptr> &child){ auto collector=mHandler.getCollector(subrule_id); if (collector){ mAssignments.push_back(Assignment<_parserElementT>(collector, begin, count, child)); } } template _parserElementT HandlerContext<_parserElementT>::realize(const string &input, size_t begin, size_t count){ _parserElementT ret=mHandler.invoke(input, begin, count); for (auto it=mAssignments.begin(); it!=mAssignments.end(); ++it){ (*it).invoke(ret,input); } return ret; } template shared_ptr> HandlerContext<_parserElementT>::branch(){ return mHandler.createContext(); } template void HandlerContext<_parserElementT>::merge(const shared_ptr> &other){ for (auto it=other->mAssignments.begin();it!=other->mAssignments.end();++it){ mAssignments.emplace_back(*it); } } template size_t HandlerContext<_parserElementT>::getLastIterator()const{ return mAssignments.size(); } template void HandlerContext<_parserElementT>::undoAssignments(size_t pos){ mAssignments.erase(mAssignments.begin()+pos,mAssignments.end()); } template void HandlerContext< _parserElementT >::recycle(){ mAssignments.clear(); mHandler.releaseContext(static_pointer_cast>(shared_from_this())); } // // ParserHandlerBase template class implementation // template ParserHandlerBase<_parserElementT>::ParserHandlerBase(const Parser<_parserElementT> &parser, const string &name) : mParser(parser), mRulename(tolower(name)), mCachedContext(NULL) { } template void ParserHandlerBase<_parserElementT>::installCollector(const string &rulename, const shared_ptr> &collector){ shared_ptr rec=mParser.mGrammar->findRule(rulename); if (!rec){ cerr<<"There is no rule '"<getId()]=collector; } template const shared_ptr> & ParserHandlerBase<_parserElementT>::getCollector(unsigned int rule_id)const{ auto it=mCollectors.find(rule_id); if (it!=mCollectors.end()) return (*it).second; return mParser.mNullCollector; } template void ParserHandlerBase< _parserElementT >::releaseContext(const shared_ptr> &ctx){ mCachedContext=ctx; } template shared_ptr> ParserHandlerBase<_parserElementT>::createContext(){ if (mCachedContext) { shared_ptr> ret=mCachedContext; mCachedContext.reset(); return ret; } return make_shared>(this->shared_from_this()); } // // ParserHandler template implementation // template _parserElementT ParserHandler<_derivedParserElementT,_parserElementT>::invoke(const string &input, size_t begin, size_t count){ if (mHandlerCreateFunc) return universal_pointer_cast<_parserElementT>(mHandlerCreateFunc()); if (mHandlerCreateDebugFunc) return universal_pointer_cast<_parserElementT>(mHandlerCreateDebugFunc(this->getRulename(), input.substr(begin, count))); return NULL; } // // ParserContext template class implementation // template ParserContext<_parserElementT>::ParserContext(Parser<_parserElementT> &parser) : mParser(parser) { } template void ParserContext<_parserElementT>::_beginParse(ParserLocalContext & lctx, const shared_ptr &rec){ shared_ptr ctx; auto h=mParser.getHandler(rec->getId()); if (h){ ctx=h->createContext(); mHandlerStack.push_back(static_pointer_cast>(ctx)); } lctx.set(ctx,rec,mHandlerStack.back()->getLastIterator()); } template void ParserContext<_parserElementT>::_endParse(const ParserLocalContext &localctx, const string &input, size_t begin, size_t count){ if (localctx.mHandlerContext){ mHandlerStack.pop_back(); if (count!=string::npos && count>0){ if (!mHandlerStack.empty()){ /*assign object to parent */ mHandlerStack.back()->setChild(localctx.mRecognizer->getId(), begin, count, static_pointer_cast> (localctx.mHandlerContext)); }else{ /*no parent, this is our root object*/ mRoot=static_pointer_cast>(localctx.mHandlerContext); } }else{ //no match static_pointer_cast>(localctx.mHandlerContext)->recycle(); } }else{ if (count!=string::npos && count>0){ /*assign string to parent */ if (localctx.mRecognizer->getId()!=0) mHandlerStack.back()->setChild(localctx.mRecognizer->getId(), begin, count, NULL); }else{ mHandlerStack.back()->undoAssignments(localctx.mAssignmentPos); } } } template _parserElementT ParserContext<_parserElementT>::createRootObject(const string &input){ return mRoot ? mRoot->realize(input,0,input.size()) : NULL; } template shared_ptr> ParserContext<_parserElementT>::_branch(){ if (mHandlerStack.empty()){ cerr<<"Cannot branch while stack is empty"<> ret=mHandlerStack.back()->branch(); mHandlerStack.push_back(ret); return ret; } template void ParserContext<_parserElementT>::_merge(const shared_ptr> &other){ if (mHandlerStack.back()!=other){ cerr<<"The branch being merged is not the last one of the stack !"<merge(other); other->recycle(); } template void ParserContext<_parserElementT>::_removeBranch(const shared_ptr> &other){ auto it=find(mHandlerStack.rbegin(), mHandlerStack.rend(),other); if (it==mHandlerStack.rend()){ cerr<<"A branch could not be found in the stack while removing it !"<recycle(); } template void ParserContext<_parserElementT>::beginParse(ParserLocalContext &ctx, const shared_ptr &rec){ _beginParse(ctx, rec); } template void ParserContext<_parserElementT>::endParse(const ParserLocalContext &localctx, const string &input, size_t begin, size_t count){ _endParse(localctx, input, begin, count); } template shared_ptr ParserContext<_parserElementT>::branch(){ return _branch(); } template void ParserContext<_parserElementT>::merge(const shared_ptr &other){ _merge(static_pointer_cast>(other)); } template void ParserContext<_parserElementT>::removeBranch(const shared_ptr &other){ _removeBranch(static_pointer_cast>(other)); } // // Parser template class implementation // template Parser<_parserElementT>::Parser(const shared_ptr &grammar) : mGrammar(grammar) { if (!mGrammar->isComplete()){ cerr<<"Grammar not complete, aborting."< shared_ptr> &Parser<_parserElementT>::getHandler(unsigned int rule_id){ auto it=mHandlers.find(rule_id); if (it==mHandlers.end()) return mNullHandler; return (*it).second; } template void Parser<_parserElementT>::installHandler(const shared_ptr> &handler){ shared_ptr rec=mGrammar->findRule(handler->getRulename()); if (rec==NULL){ cerr<<"There is no rule '"<getRulename()<<"' in the grammar."<getId()]=handler; } template _parserElementT Parser<_parserElementT>::parseInput(const string &rulename, const string &input, size_t *parsed_size){ size_t parsed; shared_ptr rec=mGrammar->getRule(rulename); auto pctx=make_shared>(*this); //auto t_start = std::chrono::high_resolution_clock::now(); parsed=rec->feed(pctx, input, 0); //auto t_end = std::chrono::high_resolution_clock::now(); //cout<<"Recognition done in "<(t_end-t_start).count()<<" milliseconds"<createRootObject(input); return ret; } }