Commit e53b79ec authored by Simon Morlat's avatar Simon Morlat

optimizations. parsing time around 5ms for a SIP register.

parent a45ed80d
......@@ -176,16 +176,20 @@ shared_ptr<Loop> Foundation::loop(){
return make_shared<Loop>();
}
/*
* TODO: could be optimized() with strcmp with a specialized Recognizer !
*/
shared_ptr<Recognizer> Utils::literal(const string & lt){
shared_ptr<Sequence> seq=Foundation::sequence();
Literal::Literal(const string& lit) : mLiteral(tolower(lit)){
mLiteralSize=mLiteral.size();
}
size_t Literal::_feed(const shared_ptr< ParserContextBase >& ctx, const string& input, size_t pos){
size_t i;
for (i=0;i<lt.size();++i){
seq->addRecognizer(Foundation::charRecognizer(lt[i],false));
for(i=0;i<mLiteralSize;++i){
if (::tolower(input[pos+i])!=mLiteral[i]) return string::npos;
}
return seq;
return mLiteralSize;
}
shared_ptr<Recognizer> Utils::literal(const string & lt){
return make_shared<Literal>(lt);
}
shared_ptr<Recognizer> Utils::char_range(int begin, int end){
......@@ -253,12 +257,20 @@ void Grammar::_extendRule(const string &argname, const shared_ptr<Recognizer> &r
}
}
shared_ptr<Recognizer> Grammar::getRule(const string &argname){
shared_ptr<Recognizer> ret;
shared_ptr<Recognizer> Grammar::findRule(const string &argname){
string name=tolower(argname);
auto it=mRules.find(name);
if (it!=mRules.end()){
shared_ptr<RecognizerPointer> pointer=dynamic_pointer_cast<RecognizerPointer>((*it).second);
return (*it).second;
}
return NULL;
}
shared_ptr<Recognizer> Grammar::getRule(const string &argname){
shared_ptr<Recognizer> ret=findRule(argname);
if (ret){
shared_ptr<RecognizerPointer> pointer=dynamic_pointer_cast<RecognizerPointer>(ret);
if (pointer){
if (pointer->getPointed()){/*if pointer is defined return the pointed value directly*/
return pointer->getPointed();
......@@ -266,9 +278,10 @@ shared_ptr<Recognizer> Grammar::getRule(const string &argname){
return pointer;
}
}
return (*it).second;
return ret;
}else{/*the rule doesn't exist yet: return a pointer*/
ret=make_shared<RecognizerPointer>();
string name=tolower(argname);
ret->setName(string("@")+name);
mRules[name]=ret;
}
......
......@@ -38,15 +38,6 @@ private:
bool mCaseSensitive;
};
/*this is an optimization of a selector with multiple individual char recognizer*/
class CharRange : public Recognizer{
public:
CharRange(int begin, int end);
private:
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
int mBegin,mEnd;
};
class Selector : public Recognizer{
public:
Selector();
......@@ -92,6 +83,24 @@ public:
static shared_ptr<Loop> loop();
};
/*this is an optimization of a selector with multiple individual char recognizer*/
class CharRange : public Recognizer{
public:
CharRange(int begin, int end);
private:
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
int mBegin,mEnd;
};
class Literal : public Recognizer{
public:
Literal(const string &lit);
private:
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
string mLiteral;
size_t mLiteralSize;
};
class Utils{
public:
static shared_ptr<Recognizer> literal(const string & lt);
......@@ -125,6 +134,10 @@ public:
_extendRule(name, rule);
return rule;
}
shared_ptr<Recognizer> findRule(const string &name);
/*
* getRule() never returns NULL. If the rule is not (yet) defined, it returns an undefined pointer, that will be set later if the rule gets defined.
**/
shared_ptr<Recognizer> getRule(const string &name);
bool isComplete()const;
int getNumRules()const;
......
......@@ -78,8 +78,8 @@ HandlerContext<_parserElementT>::HandlerContext(const shared_ptr<ParserHandlerBa
}
template <typename _parserElementT>
void HandlerContext<_parserElementT>::setChild(const string &subrule_name, size_t begin, size_t count, const shared_ptr<HandlerContext<_parserElementT>> &child){
auto collector=mHandler->getCollector(subrule_name);
void HandlerContext<_parserElementT>::setChild(unsigned int subrule_id, size_t begin, size_t count, const shared_ptr<HandlerContext<_parserElementT>> &child){
auto collector=mHandler->getCollector(subrule_id);
if (collector){
mAssignments.push_back(Assignment<_parserElementT>(collector, begin, count, child));
}
......@@ -126,12 +126,17 @@ ParserHandlerBase<_parserElementT>::ParserHandlerBase(const Parser<_parserElemen
template <typename _parserElementT>
void ParserHandlerBase<_parserElementT>::installCollector(const string &rulename, const shared_ptr<AbstractCollector<_parserElementT>> &collector){
mCollectors[tolower(rulename)]=collector;
shared_ptr<Recognizer> rec=mParser.mGrammar->findRule(rulename);
if (!rec){
cerr<<"There is no rule '"<<rulename<<"' in the grammar."<<endl;
return;
}
mCollectors[rec->getId()]=collector;
}
template <typename _parserElementT>
const shared_ptr<AbstractCollector<_parserElementT>> & ParserHandlerBase<_parserElementT>::getCollector(const string &rulename)const{
auto it=mCollectors.find(rulename);
const shared_ptr<AbstractCollector<_parserElementT>> & ParserHandlerBase<_parserElementT>::getCollector(unsigned int rule_id)const{
auto it=mCollectors.find(rule_id);
if (it!=mCollectors.end()) return (*it).second;
return mParser.mNullCollector;
}
......@@ -157,7 +162,7 @@ template <typename _parserElementT>
ParserLocalContext ParserContext<_parserElementT>::_beginParse(const shared_ptr<Recognizer> &rec){
shared_ptr<HandlerContextBase> ctx;
auto h=mParser.getHandler(rec->getName());
auto h=mParser.getHandler(rec->getId());
if (h){
ctx=h->createContext();
mHandlerStack.push_back(static_pointer_cast<HandlerContext<_parserElementT>>(ctx));
......@@ -172,7 +177,7 @@ void ParserContext<_parserElementT>::_endParse(const ParserLocalContext &localct
if (count!=string::npos && count>0){
if (!mHandlerStack.empty()){
/*assign object to parent */
mHandlerStack.back()->setChild(localctx.mRecognizer->getName(), begin, count,
mHandlerStack.back()->setChild(localctx.mRecognizer->getId(), begin, count,
static_pointer_cast<HandlerContext< _parserElementT >> (localctx.mHandlerContext));
}else{
......@@ -183,7 +188,7 @@ void ParserContext<_parserElementT>::_endParse(const ParserLocalContext &localct
}else{
if (count!=string::npos && count>0){
/*assign string to parent */
mHandlerStack.back()->setChild(localctx.mRecognizer->getName(), begin, count, NULL);
mHandlerStack.back()->setChild(localctx.mRecognizer->getId(), begin, count, NULL);
}else{
mHandlerStack.back()->undoAssignments(localctx.mAssignmentPos);
}
......@@ -270,15 +275,20 @@ Parser<_parserElementT>::Parser(const shared_ptr<Grammar> &grammar) : mGrammar(g
}
template <typename _parserElementT>
shared_ptr<ParserHandlerBase<_parserElementT>> &Parser<_parserElementT>::getHandler(const string &rulename){
auto it=mHandlers.find(rulename);
shared_ptr<ParserHandlerBase<_parserElementT>> &Parser<_parserElementT>::getHandler(unsigned int rule_id){
auto it=mHandlers.find(rule_id);
if (it==mHandlers.end()) return mNullHandler;
return (*it).second;
}
template <typename _parserElementT>
void Parser<_parserElementT>::installHandler(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler){
mHandlers[handler->getRulename()]=handler;
shared_ptr<Recognizer> rec=mGrammar->findRule(handler->getRulename());
if (rec==NULL){
cerr<<"There is no rule '"<<handler->getRulename()<<"' in the grammar."<<endl;
return;
}
mHandlers[rec->getId()]=handler;
}
template <typename _parserElementT>
......
......@@ -62,9 +62,9 @@ public:
}
protected:
void installCollector(const string &rulename, const shared_ptr<AbstractCollector<_parserElementT>> &collector);
const shared_ptr<AbstractCollector<_parserElementT>> &getCollector(const string &rulename)const;
const shared_ptr<AbstractCollector<_parserElementT>> &getCollector(unsigned int rule_id)const;
private:
map<string, shared_ptr<AbstractCollector<_parserElementT>> > mCollectors;
map<unsigned int, shared_ptr<AbstractCollector<_parserElementT>> > mCollectors;
const Parser<_parserElementT> &mParser;
string mRulename;
};
......@@ -121,7 +121,7 @@ template <typename _parserElementT>
class HandlerContext : public HandlerContextBase{
public:
HandlerContext(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler);
void setChild(const string &subrule_name, size_t begin, size_t count, const shared_ptr<HandlerContext> &child);
void setChild(unsigned int subrule_id, size_t begin, size_t count, const shared_ptr<HandlerContext> &child);
_parserElementT realize(const string &input, size_t begin, size_t count);
shared_ptr<HandlerContext<_parserElementT>> branch();
void merge(const shared_ptr<HandlerContext<_parserElementT>> &other);
......@@ -195,10 +195,10 @@ public:
}
_parserElementT parseInput(const string &rulename, const string &input, size_t *parsed_size);
private:
shared_ptr<ParserHandlerBase<_parserElementT>> &getHandler(const string &rulename);
shared_ptr<ParserHandlerBase<_parserElementT>> &getHandler(unsigned int);
void installHandler(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler);
shared_ptr<Grammar> mGrammar;
map<string, shared_ptr<ParserHandlerBase<_parserElementT>>> mHandlers;
map<unsigned int, shared_ptr<ParserHandlerBase<_parserElementT>>> mHandlers;
shared_ptr<ParserHandlerBase<_parserElementT>> mNullHandler;
shared_ptr<AbstractCollector<_parserElementT>> mNullCollector;
};
......
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