Commit 734c22de authored by Simon Morlat's avatar Simon Morlat

optimize memory allocations by using a vector of assignments which is...

optimize memory allocations by using a vector of assignments which is cleaned() in case of rule aborted, instead of context created and spliced to parent at each stage.
parent c917d609
......@@ -83,21 +83,18 @@ ParserContext<_parserElementT>::ParserContext(Parser<_parserElementT> &parser) :
template <typename _parserElementT>
ParserLocalContext ParserContext<_parserElementT>::_beginParse(const shared_ptr<Recognizer> &rec){
shared_ptr<HandlerContextBase> ctx;
bool isBranch=false;
auto it=mParser.mHandlers.find(rec->getName());
if (it!=mParser.mHandlers.end()){
ctx=(*it).second->createContext();
mHandlerStack.push_back(static_pointer_cast<HandlerContext<_parserElementT>>(ctx));
}else{
isBranch=true;
ctx=branch();
}
return ParserLocalContext(ctx,rec,isBranch);
return ParserLocalContext(ctx,rec,mHandlerStack.back()->getLastIterator());
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::_endParse(const ParserLocalContext &localctx, const string &input, size_t begin, size_t count){
if (!localctx.mIsBranch){
if (localctx.mHandlerContext){
mHandlerStack.pop_back();
if (count!=string::npos && count>0){
if (!mHandlerStack.empty()){
......@@ -112,11 +109,10 @@ void ParserContext<_parserElementT>::_endParse(const ParserLocalContext &localct
}
}else{
if (count!=string::npos && count>0){
merge(localctx.mHandlerContext);
/*assign string to parent */
mHandlerStack.back()->setChild(localctx.mRecognizer->getName(), begin, count, NULL);
}else{
removeBranch(localctx.mHandlerContext);
mHandlerStack.back()->undoAssignments(localctx.mAssignmentPos);
}
}
}
......
......@@ -2,9 +2,11 @@
#define parser_hh
#include <functional>
#include <vector>
#include "belr.hh"
namespace belr{
template<typename _parserElementT>
......@@ -127,36 +129,36 @@ public:
return make_shared<HandlerContext>(mHandler);
}
void merge(const shared_ptr<HandlerContext<_parserElementT>> &other){
mAssignments.splice(mAssignments.end(), other->mAssignments);
for (auto it=other->mAssignments.begin();it!=other->mAssignments.end();++it){
mAssignments.emplace_back(*it);
}
//mAssignments.splice(mAssignments.end(), other->mAssignments);
}
typename list<Assignment<_parserElementT>>::iterator getLastIterator(){
if (mAssignments.empty())
return mAssignments.end();
return --mAssignments.end();
bool hasCollectors()const{
return !mHandler->mCollectors.empty();
}
void undoAssignments(const typename list<Assignment<_parserElementT>>::iterator &last_valid){
if (mAssignments.end()==last_valid){
mAssignments.clear();
}else{
mAssignments.erase(++last_valid,mAssignments.end());
}
size_t getLastIterator(){
return mAssignments.size();
}
void undoAssignments(size_t pos){
mAssignments.erase(mAssignments.begin()+pos,mAssignments.end());
}
private:
shared_ptr<ParserHandlerBase<_parserElementT>> mHandler;
list<Assignment<_parserElementT>> mAssignments;
vector<Assignment<_parserElementT>> mAssignments;
};
template <typename _parserElementT>
class Parser;
struct ParserLocalContext{
ParserLocalContext(const shared_ptr<HandlerContextBase>& hc, const shared_ptr<Recognizer>& rec, bool isBranch)
: mHandlerContext(hc), mRecognizer(rec), mIsBranch(isBranch){
ParserLocalContext(const shared_ptr<HandlerContextBase>& hc, const shared_ptr<Recognizer>& rec, size_t pos)
: mHandlerContext(hc), mRecognizer(rec), mAssignmentPos(pos){
}
shared_ptr<HandlerContextBase> mHandlerContext;
shared_ptr<Recognizer> mRecognizer;
bool mIsBranch;
const shared_ptr<Recognizer> &mRecognizer;
size_t mAssignmentPos;
};
class ParserContextBase{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment