Commit e6b532c1 authored by Simon Morlat's avatar Simon Morlat

clean code

parent 734c22de
......@@ -7,8 +7,8 @@ AC_CONFIG_SRCDIR([src/belr.hh])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
AC_PROG_LIBTOOL
AM_SILENT_RULES(yes)
LT_INIT(disable-shared win32-dll)
# Checks for programs.
AC_PROG_CXX
......
......@@ -67,12 +67,85 @@ void Assignment<_parserElementT>::invoke(_parserElementT parent, const string &i
}
}
//
// HandlerContext template implementation
//
template <typename _parserElementT>
HandlerContext<_parserElementT>::HandlerContext(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler) :
mHandler(handler){
}
template <typename _parserElementT>
void HandlerContext<_parserElementT>::setChild(const string &subrule_name, size_t begin, size_t count, const shared_ptr<HandlerContext<_parserElementT>> &child){
auto it=mHandler->mCollectors.find(subrule_name);
if (it!=mHandler->mCollectors.end()){
mAssignments.push_back(Assignment<_parserElementT>((*it).second, begin, count, child));
}
}
template <typename _parserElementT>
_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 <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> HandlerContext<_parserElementT>::branch(){
return make_shared<HandlerContext>(mHandler);
}
template <typename _parserElementT>
void HandlerContext<_parserElementT>::merge(const shared_ptr<HandlerContext<_parserElementT>> &other){
for (auto it=other->mAssignments.begin();it!=other->mAssignments.end();++it){
mAssignments.emplace_back(*it);
}
}
template <typename _parserElementT>
size_t HandlerContext<_parserElementT>::getLastIterator()const{
return mAssignments.size();
}
template <typename _parserElementT>
void HandlerContext<_parserElementT>::undoAssignments(size_t pos){
mAssignments.erase(mAssignments.begin()+pos,mAssignments.end());
}
//
// ParserHandlerBase template class implementation
//
template <typename _parserElementT>
ParserHandlerBase<_parserElementT>::ParserHandlerBase(const string &name) : mRulename(tolower(name)){
}
template <typename _parserElementT>
void ParserHandlerBase<_parserElementT>::installCollector(const string &rulename, const shared_ptr<AbstractCollector<_parserElementT>> &collector){
mCollectors[tolower(rulename)]=collector;
}
template <typename _parserElementT>
const shared_ptr<AbstractCollector<_parserElementT>> & ParserHandlerBase<_parserElementT>::getCollector(const string &rulename)const{
auto it=mCollectors.find(rulename);
if (it!=mCollectors.end()) return (*it).second;
return NULL;
}
//
// ParserHandler template implementation
//
template <typename _derivedParserElementT, typename _parserElementT>
_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(mRulename, input.substr(begin, count)));
return universal_pointer_cast<_parserElementT>(mHandlerCreateDebugFunc(this->getRulename(), input.substr(begin, count)));
return NULL;
}
......@@ -183,7 +256,11 @@ template <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> ParserHandlerBase<_parserElementT>::createContext(){
return make_shared<HandlerContext<_parserElementT>>(this->shared_from_this());
}
//
// Parser template class implementation
//
template <typename _parserElementT>
Parser<_parserElementT>::Parser(const shared_ptr<Grammar> &grammar) : mGrammar(grammar){
if (!mGrammar->isComplete()){
......@@ -192,16 +269,28 @@ 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);
if (it=mHandlers.end()) return NULL;
return (*it).second;
}
template <typename _parserElementT>
void Parser<_parserElementT>::installHandler(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler){
mHandlers[handler->getRulename()]=handler;
}
template <typename _parserElementT>
_parserElementT Parser<_parserElementT>::parseInput(const string &rulename, const string &input, size_t *parsed_size){
size_t parsed;
shared_ptr<Recognizer> rec=mGrammar->getRule(rulename);
auto pctx=make_shared<ParserContext<_parserElementT>>(*this);
auto t_start = std::chrono::high_resolution_clock::now();
//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 "<<std::chrono::duration<double, std::milli>(t_end-t_start).count()<<" milliseconds"<<endl;
//auto t_end = std::chrono::high_resolution_clock::now();
//cout<<"Recognition done in "<<std::chrono::duration<double, std::milli>(t_end-t_start).count()<<" milliseconds"<<endl;
if (parsed_size) *parsed_size=parsed;
auto ret= pctx->createRootObject(input);
return ret;
......
......@@ -51,39 +51,46 @@ template <typename _parserElementT>
class ParserHandlerBase : public enable_shared_from_this<ParserHandlerBase<_parserElementT>>{
friend class HandlerContext<_parserElementT>;
public:
ParserHandlerBase(const string &name);
virtual _parserElementT invoke(const string &input, size_t begin, size_t count)=0;
shared_ptr<HandlerContext<_parserElementT>> createContext();
const string &getRulename()const{
return mRulename;
}
protected:
void installCollector(const string &rulename, const shared_ptr<AbstractCollector<_parserElementT>> &collector);
const shared_ptr<AbstractCollector<_parserElementT>> &getCollector(const string &rulename)const;
private:
map<string, shared_ptr<AbstractCollector<_parserElementT>> > mCollectors;
string mRulename;
};
template <typename _derivedParserElementT, typename _parserElementT>
class ParserHandler : public ParserHandlerBase<_parserElementT>{
public:
ParserHandler(const function<_derivedParserElementT ()> &create)
: mHandlerCreateFunc(create){
ParserHandler(const string &rulename, const function<_derivedParserElementT ()> &create)
: ParserHandlerBase<_parserElementT>(rulename), mHandlerCreateFunc(create){
}
ParserHandler(const string &rulename, const function<_derivedParserElementT (const string &, const string &)> &create)
: mHandlerCreateDebugFunc(create), mRulename(rulename){
: ParserHandlerBase<_parserElementT>(rulename), mHandlerCreateDebugFunc(create){
}
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setCollector(const string &child_rule_name, function<void (_derivedParserElementT , const string & )> fn){
this->mCollectors[tolower(child_rule_name)]=make_shared<ParserCollector<_derivedParserElementT,_parserElementT,const string&>>(fn);
this->installCollector(child_rule_name, make_shared<ParserCollector<_derivedParserElementT,_parserElementT,const string&>>(fn));
return static_pointer_cast<ParserHandler<_derivedParserElementT,_parserElementT>>(this->shared_from_this());
}
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setCollector(const string &child_rule_name, function<void (_derivedParserElementT , int )> fn){
this->mCollectors[tolower(child_rule_name)]=make_shared<ParserCollector<_derivedParserElementT,_parserElementT,int>>(fn);
this->installCollector(child_rule_name, make_shared<ParserCollector<_derivedParserElementT,_parserElementT,int>>(fn));
return static_pointer_cast<ParserHandler<_derivedParserElementT,_parserElementT>>(this->shared_from_this());
}
template <typename _valueT>
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setCollector(const string &child_rule_name, function<void (_derivedParserElementT , _valueT)> fn){
this->mCollectors[tolower(child_rule_name)]=make_shared<ParserChildCollector<_derivedParserElementT,_parserElementT,_valueT>>(fn);
this->installCollector(child_rule_name, make_shared<ParserChildCollector<_derivedParserElementT,_parserElementT,_valueT>>(fn));
return static_pointer_cast<ParserHandler<_derivedParserElementT,_parserElementT>>(this->shared_from_this());
}
_parserElementT invoke(const string &input, size_t begin, size_t count);
private:
function<_derivedParserElementT ()> mHandlerCreateFunc;
function<_derivedParserElementT (const string &, const string &)> mHandlerCreateDebugFunc;
string mRulename;
};
template <typename _parserElementT>
......@@ -109,41 +116,13 @@ public:
template <typename _parserElementT>
class HandlerContext : public HandlerContextBase{
public:
HandlerContext(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler) :
mHandler(handler){
}
void setChild(const string &subrule_name, size_t begin, size_t count, const shared_ptr<HandlerContext> &child){
auto it=mHandler->mCollectors.find(subrule_name);
if (it!=mHandler->mCollectors.end()){
mAssignments.push_back(Assignment<_parserElementT>((*it).second, begin, count, child));
}
}
_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;
}
shared_ptr<HandlerContext<_parserElementT>> branch(){
return make_shared<HandlerContext>(mHandler);
}
void merge(const shared_ptr<HandlerContext<_parserElementT>> &other){
for (auto it=other->mAssignments.begin();it!=other->mAssignments.end();++it){
mAssignments.emplace_back(*it);
}
//mAssignments.splice(mAssignments.end(), other->mAssignments);
}
bool hasCollectors()const{
return !mHandler->mCollectors.empty();
}
size_t getLastIterator(){
return mAssignments.size();
}
void undoAssignments(size_t pos){
mAssignments.erase(mAssignments.begin()+pos,mAssignments.end());
}
HandlerContext(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler);
void setChild(const string &subrule_name, 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);
size_t getLastIterator()const;
void undoAssignments(size_t pos);
private:
shared_ptr<ParserHandlerBase<_parserElementT>> mHandler;
vector<Assignment<_parserElementT>> mAssignments;
......@@ -199,22 +178,23 @@ public:
Parser(const shared_ptr<Grammar> &grammar);
template <typename _derivedParserElementT>
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setHandler(const string &rulename,const function<_derivedParserElementT ()> & handler){
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> ret;
mHandlers[tolower(rulename)]=ret=make_shared<ParserHandler<_derivedParserElementT,_parserElementT>>(handler);
auto ret=make_shared<ParserHandler<_derivedParserElementT,_parserElementT>>(rulename,handler);
installHandler(ret);
return ret;
}
template <typename _derivedParserElementT>
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setHandler(const string &rulename,
const function<_derivedParserElementT (const string &, const string &)> & handler){
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> ret;
string rulename_lc=tolower(rulename);
mHandlers[rulename_lc]=ret=make_shared<ParserHandler<_derivedParserElementT,_parserElementT>>(rulename_lc,handler);
auto ret=make_shared<ParserHandler<_derivedParserElementT,_parserElementT>>(rulename,handler);
installHandler(ret);
return ret;
}
_parserElementT parseInput(const string &rulename, const string &input, size_t *parsed_size);
private:
shared_ptr<ParserHandlerBase<_parserElementT>> &getHandler(const string &rulename);
void installHandler(const shared_ptr<ParserHandlerBase<_parserElementT>> &handler);
shared_ptr<Grammar> mGrammar;
map<string, shared_ptr<ParserHandlerBase<_parserElementT>>> mHandlers;
};
......
......@@ -8,42 +8,65 @@
#include <sstream>
#include <chrono>
#include <ctime>
#include <cstring>
using namespace::belr;
int main(int argc, char *argv[]){
const char *file=NULL,*message_file=NULL;
int rules_first=0;
int i;
int repeat_count=1;
if (argc<2){
cerr<<argv[0]<< " <grammarfile-to-load> [<input file>] [rule1] [rule2]..."<<endl;
cerr<<argv[0]<< " [--repeat <count>] <grammarfile-to-load> [<input file>] [rule1] [rule2]..."<<endl;
return -1;
}
for(i=1;i<argc;++i){
if (strcmp(argv[i],"--repeat")==0){
++i;
if (i<argc){
repeat_count=atoi(argv[i]);
}
}else{
file=argv[i];
++i;
if (i<argc)
message_file=argv[i];
break;
}
}
rules_first=i+1;
ABNFGrammarBuilder builder;
shared_ptr<Grammar> grammar=make_shared<Grammar>(argv[1]);
shared_ptr<Grammar> grammar=make_shared<Grammar>(file);
grammar->include(make_shared<CoreRules>());
builder.createFromAbnf(argv[1],grammar);
builder.createFromAbnf(file,grammar);
if (argc>3){
ifstream istr(argv[2]);
if (message_file){
ifstream istr(message_file);
if (!istr.is_open()){
cerr<<"Could not open "<<argv[2]<<endl;
cerr<<"Could not open "<<message_file<<endl;
return -1;
}
stringstream str;
str<<istr.rdbuf();
DebugParser parser(grammar);
list<string> rules;
for(int i=3; i<argc; ++i){
for(int i=rules_first; i<argc; ++i){
rules.push_back(argv[i]);
}
parser.setObservedRules(rules);
size_t parsed;
shared_ptr<DebugElement> ret;
auto t_start = std::chrono::high_resolution_clock::now();
auto ret=parser.parseInput(argv[3],str.str(),&parsed);
for(int r=0;r<repeat_count;++r){
ret=parser.parseInput(argv[rules_first],str.str(),&parsed);
}
auto t_end = std::chrono::high_resolution_clock::now();
if (parsed<str.str().size()){
cerr<<"Parsing ended prematuraly at pos "<<parsed<<endl;
}else{
cout<<"Parsing done in "<<std::chrono::duration<double, std::milli>(t_end-t_start).count()<<" milliseconds"<<endl;
cout<<"Parsing done in "<<std::chrono::duration<double, std::milli>(t_end-t_start).count()/repeat_count<<" milliseconds"<<endl;
}
if (ret){
ret->tostream(0,cout);
......
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