Commit 97a8c821 authored by Simon Morlat's avatar Simon Morlat

templatized parser, with the base type for all parsed elements.

parent a9f7564e
......@@ -18,10 +18,10 @@ const string &Recognizer::getName()const{
return mName;
}
size_t Recognizer::feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t Recognizer::feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
size_t match;
shared_ptr<HandlerContext> hctx=ctx->beginParse(shared_from_this());
shared_ptr<HandlerContextBase> hctx=ctx->beginParse(shared_from_this());
match=_feed(ctx, input, pos);
if (match!=string::npos && match>0){
if (0 && mName.size()>0){
......@@ -43,7 +43,7 @@ CharRecognizer::CharRecognizer(int to_recognize, bool caseSensitive) : mToRecogn
}
}
size_t CharRecognizer::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t CharRecognizer::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
if (mCaseSensitive){
return input[pos]==mToRecognize ? 1 : string::npos;
}
......@@ -58,10 +58,10 @@ shared_ptr<Selector> Selector::addRecognizer(const shared_ptr<Recognizer> &r){
return static_pointer_cast<Selector> (shared_from_this());
}
size_t Selector::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t Selector::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
size_t matched=0;
size_t bestmatch=0;
shared_ptr<HandlerContext> bestBranch;
shared_ptr<HandlerContextBase> bestBranch;
for (auto it=mElements.begin(); it!=mElements.end(); ++it){
auto br=ctx->branch();
......@@ -84,7 +84,7 @@ size_t Selector::_feed(const shared_ptr<ParserContext> &ctx, const string &input
ExclusiveSelector::ExclusiveSelector(){
}
size_t ExclusiveSelector::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t ExclusiveSelector::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
size_t matched=0;
for (auto it=mElements.begin(); it!=mElements.end(); ++it){
......@@ -105,7 +105,7 @@ shared_ptr<Sequence> Sequence::addRecognizer(const shared_ptr<Recognizer> &eleme
return static_pointer_cast<Sequence>( shared_from_this());
}
size_t Sequence::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t Sequence::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
size_t matched=0;
size_t total=0;
......@@ -132,7 +132,7 @@ shared_ptr<Loop> Loop::setRecognizer(const shared_ptr<Recognizer> &element, int
return static_pointer_cast<Loop>(shared_from_this());
}
size_t Loop::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t Loop::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
size_t matched=0;
size_t total=0;
int repeat;
......@@ -150,7 +150,7 @@ size_t Loop::_feed(const shared_ptr<ParserContext> &ctx, const string &input, si
CharRange::CharRange(int begin, int end) : mBegin(begin), mEnd(end){
}
size_t CharRange::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t CharRange::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
int c=input[pos];
if (c>=mBegin && c<=mEnd) return 1;
return string::npos;
......@@ -192,7 +192,7 @@ shared_ptr<Recognizer> RecognizerPointer::getPointed(){
return mRecognizer;
}
size_t RecognizerPointer::_feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos){
size_t RecognizerPointer::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
if (mRecognizer){
return mRecognizer->feed(ctx, input, pos);
}else{
......
......@@ -12,16 +12,16 @@ namespace belr{
string tolower(const string &str);
class ParserContext;
class ParserContextBase;
class Recognizer : public enable_shared_from_this<Recognizer>{
public:
void setName(const string &name);
const string &getName()const;
size_t feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
size_t feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
protected:
Recognizer();
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos)=0;
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos)=0;
string mName;
};
......@@ -29,7 +29,7 @@ class CharRecognizer : public Recognizer{
public:
CharRecognizer(int to_recognize, bool caseSensitive=false);
private:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
int mToRecognize;
bool mCaseSensitive;
};
......@@ -39,7 +39,7 @@ class CharRange : public Recognizer{
public:
CharRange(int begin, int end);
private:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
int mBegin,mEnd;
};
......@@ -48,7 +48,7 @@ public:
Selector();
shared_ptr<Selector> addRecognizer(const shared_ptr<Recognizer> &element);
protected:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
list<shared_ptr<Recognizer>> mElements;
};
......@@ -57,7 +57,7 @@ class ExclusiveSelector : public Selector{
public:
ExclusiveSelector();
private:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
};
class Sequence : public Recognizer{
......@@ -65,7 +65,7 @@ public:
Sequence();
shared_ptr<Sequence> addRecognizer(const shared_ptr<Recognizer> &element);
private:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
list<shared_ptr<Recognizer>> mElements;
};
......@@ -74,7 +74,7 @@ public:
Loop();
shared_ptr<Loop> setRecognizer(const shared_ptr<Recognizer> &element, int min=0, int max=-1);
private:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
shared_ptr<Recognizer> mRecognizer;
int mMin, mMax;
};
......@@ -100,7 +100,7 @@ public:
shared_ptr<Recognizer> getPointed();
void setPointed(const shared_ptr<Recognizer> &r);
private:
virtual size_t _feed(const shared_ptr<ParserContext> &ctx, const string &input, size_t pos);
virtual size_t _feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos);
shared_ptr<Recognizer> mRecognizer;
};
......
#include "abnf.hh"
#include "grammarbuilder.hh"
#include "parser-impl.cc"
#include <iostream>
......
......@@ -15,7 +15,7 @@ private:
void addRule(void *list, void *rule);
void *createRuleList();
void *createRule();
Parser mParser;
Parser<void*> mParser;
};
}
......
#include "parser.hh"
#include <iostream>
#include <algorithm>
namespace belr{
template <typename _parserElementT>
void Assignment<_parserElementT>::invoke(_parserElementT parent, const string &input){
if (mChild){
shared_ptr<ParserCollector<_parserElementT,_parserElementT>> cc=dynamic_pointer_cast<ParserCollector<_parserElementT,_parserElementT>>(mCollector);
if (cc){
cc->invoke(parent, mChild->realize(input));
}
}else{
string value=input.substr(mBegin, mCount);
shared_ptr<ParserCollector<_parserElementT,const string&>> cc1=dynamic_pointer_cast<ParserCollector<_parserElementT,const string&>>(mCollector);
if (cc1){
cc1->invoke(parent, value);
return;
}
shared_ptr<ParserCollector<_parserElementT,const char*>> cc2=dynamic_pointer_cast<ParserCollector<_parserElementT,const char*>>(mCollector);
if (cc2){
cc2->invoke(parent, value.c_str());
return;
}
shared_ptr<ParserCollector<_parserElementT,int>> cc3=dynamic_pointer_cast<ParserCollector<_parserElementT,int>>(mCollector);
if (cc3){
cc3->invoke(parent, atoi(value.c_str()));
return;
}
}
}
template <typename _parserElementT>
ParserContext<_parserElementT>::ParserContext(Parser<_parserElementT> &parser) : mParser(parser){
}
template <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> ParserContext<_parserElementT>::_beginParse(const shared_ptr<Recognizer> &rec){
shared_ptr<HandlerContext<_parserElementT>> ctx;
auto it=mParser.mHandlers.find(rec->getName());
if (it!=mParser.mHandlers.end()){
ctx=(*it).second->createContext();
mHandlerStack.push_back(ctx);
}
return ctx;
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::_endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContext<_parserElementT>> &ctx, const string &input, size_t begin, size_t count){
if (ctx){
mHandlerStack.pop_back();
}
if (!mHandlerStack.empty()){
/*assign object to parent */
mHandlerStack.back()->setChild(rec->getName(), begin, count, ctx);
}else{
/*no parent, this is our root object*/
mRoot=ctx;
}
}
template <typename _parserElementT>
_parserElementT ParserContext<_parserElementT>::createRootObject(const string &input){
return mRoot ? mRoot->realize(input) : NULL;
}
template <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> ParserContext<_parserElementT>::_branch(){
shared_ptr<HandlerContext<_parserElementT>> ret=mHandlerStack.back()->branch();
mHandlerStack.push_back(ret);
return ret;
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::_merge(const shared_ptr<HandlerContext<_parserElementT>> &other){
if (mHandlerStack.back()!=other){
cerr<<"The branch being merged is not the last one of the stack !"<<endl;
abort();
}
mHandlerStack.pop_back();
return mHandlerStack.back()->merge(other);
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::_removeBranch(const shared_ptr<HandlerContext<_parserElementT>> &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 !"<<endl;
abort();
}else{
advance(it,1);
mHandlerStack.erase(it.base());
}
}
template <typename _parserElementT>
shared_ptr<HandlerContextBase> ParserContext<_parserElementT>::beginParse(const shared_ptr<Recognizer> &rec){
return static_pointer_cast<HandlerContext<_parserElementT>>(_beginParse(rec));
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContextBase> &ctx, const string &input, size_t begin, size_t count){
_endParse(rec,static_pointer_cast<HandlerContext<_parserElementT>>(ctx), input, begin, count);
}
template <typename _parserElementT>
shared_ptr<HandlerContextBase> ParserContext<_parserElementT>::branch(){
return static_pointer_cast<HandlerContext<_parserElementT>>(_branch());
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::merge(const shared_ptr<HandlerContextBase> &other){
_merge(static_pointer_cast<HandlerContext<_parserElementT>>(other));
}
template <typename _parserElementT>
void ParserContext<_parserElementT>::removeBranch(const shared_ptr<HandlerContextBase> &other){
_removeBranch(static_pointer_cast<HandlerContext<_parserElementT>>(other));
}
template <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> ParserHandler<_parserElementT>::createContext(){
return make_shared<HandlerContext<_parserElementT>>(this->shared_from_this());
}
template <typename _parserElementT>
Parser<_parserElementT>::Parser(const shared_ptr<Grammar> &grammar) : mGrammar(grammar){
if (!mGrammar->isComplete()){
cerr<<"Grammar not complete, aborting."<<endl;
return;
}
}
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);
parsed=rec->feed(pctx, input, 0);
if (parsed_size) *parsed_size=parsed;
return pctx->createRootObject(input);
}
}
#include <parser.hh>
#include <iostream>
#include <algorithm>
namespace belr{
CollectorBase::~CollectorBase(){
}
void Assignment::invoke(void *parent, const string &input){
if (mChild){
shared_ptr<ParserCollector<void*>> cc=dynamic_pointer_cast<ParserCollector<void*>>(mCollector);
if (cc){
cc->invoke(parent, mChild->realize(input));
}
}else{
string value=input.substr(mBegin, mCount);
shared_ptr<ParserCollector<const string&>> cc1=dynamic_pointer_cast<ParserCollector<const string&>>(mCollector);
if (cc1){
cc1->invoke(parent, value);
return;
}
shared_ptr<ParserCollector<const char*>> cc2=dynamic_pointer_cast<ParserCollector<const char*>>(mCollector);
if (cc2){
cc2->invoke(parent, value.c_str());
return;
}
shared_ptr<ParserCollector<int>> cc3=dynamic_pointer_cast<ParserCollector<int>>(mCollector);
if (cc3){
cc3->invoke(parent, atoi(value.c_str()));
return;
}
}
}
ParserContext::ParserContext(Parser &parser) : mParser(parser){
}
shared_ptr<HandlerContext> ParserContext::beginParse(const shared_ptr<Recognizer> &rec){
shared_ptr<HandlerContext> ctx;
auto it=mParser.mHandlers.find(rec->getName());
if (it!=mParser.mHandlers.end()){
ctx=(*it).second->createContext();
mHandlerStack.push_back(ctx);
}
return ctx;
}
void ParserContext::endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContext> &ctx, const string &input, size_t begin, size_t count){
if (ctx){
mHandlerStack.pop_back();
}
if (!mHandlerStack.empty()){
/*assign object to parent */
mHandlerStack.back()->setChild(rec->getName(), begin, count, ctx);
}else{
/*no parent, this is our root object*/
mRoot=ctx;
}
}
void *ParserContext::createRootObject(const string &input){
return mRoot ? mRoot->realize(input) : NULL;
}
shared_ptr<HandlerContext> ParserContext::branch(){
shared_ptr<HandlerContext> ret=mHandlerStack.back()->branch();
mHandlerStack.push_back(ret);
return ret;
}
void ParserContext::merge(const shared_ptr<HandlerContext> &other){
if (mHandlerStack.back()!=other){
cerr<<"The branch being merged is not the last one of the stack !"<<endl;
abort();
}
mHandlerStack.pop_back();
return mHandlerStack.back()->merge(other);
}
void ParserContext::removeBranch(const shared_ptr<HandlerContext> &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 !"<<endl;
abort();
}else{
advance(it,1);
mHandlerStack.erase(it.base());
}
}
shared_ptr<HandlerContext> ParserHandler::createContext(){
return make_shared<HandlerContext>(shared_from_this());
}
Parser::Parser(const shared_ptr<Grammar> &grammar) : mGrammar(grammar){
if (!mGrammar->isComplete()){
cerr<<"Grammar not complete, aborting."<<endl;
return;
}
}
void * Parser::parseInput(const string &rulename, const string &input, size_t *parsed_size){
size_t parsed;
shared_ptr<Recognizer> rec=mGrammar->getRule(rulename);
shared_ptr<ParserContext> pctx=make_shared<ParserContext>(*this);
parsed=rec->feed(pctx, input, 0);
if (parsed_size) *parsed_size=parsed;
return pctx->createRootObject(input);
}
}//end of namespace
\ No newline at end of file
......@@ -12,113 +12,138 @@ public:
virtual ~CollectorBase();
};
template <typename _valueT>
template <typename _parserElementT, typename _valueT>
class ParserCollector : public CollectorBase{
public:
ParserCollector(const function<void (void *, _valueT)> &fn) : mFunc(fn){
ParserCollector(const function<void (_parserElementT , _valueT)> &fn) : mFunc(fn){
}
function<void (void *, _valueT)> mFunc;
void invoke(void *obj, _valueT value){
function<void (_parserElementT, _valueT)> mFunc;
void invoke(_parserElementT obj, _valueT value){
mFunc(obj,value);
}
};
template <typename _parserElementT>
class HandlerContext;
class ParserHandler : public enable_shared_from_this<ParserHandler>{
template <typename _parserElementT>
class ParserHandler : public enable_shared_from_this<ParserHandler<_parserElementT>>{
public:
friend class HandlerContext;
ParserHandler(const function<void * ()> &create)
friend class HandlerContext<_parserElementT>;
ParserHandler(const function<_parserElementT ()> &create)
: mHandlerCreateFunc(create){
}
template <typename _valueT>
shared_ptr<ParserHandler> setCollector(const string &child_rule_name, function<void (void * , _valueT)> fn){
mCollectors[child_rule_name]=make_shared<ParserCollector<_valueT>>(fn);
return shared_from_this();
shared_ptr<ParserHandler<_parserElementT>> setCollector(const string &child_rule_name, function<void (_parserElementT , _valueT)> fn){
mCollectors[child_rule_name]=make_shared<ParserCollector<_parserElementT,_valueT>>(fn);
return this->shared_from_this();
}
void *invoke(){
_parserElementT invoke(){
return mHandlerCreateFunc();
}
shared_ptr<HandlerContext> createContext();
shared_ptr<HandlerContext<_parserElementT>> createContext();
private:
function<void * ()> mHandlerCreateFunc;
function<_parserElementT ()> mHandlerCreateFunc;
map<string, shared_ptr<CollectorBase> > mCollectors;
};
template <typename _parserElementT>
class Assignment{
private:
shared_ptr<CollectorBase> mCollector;
size_t mBegin;
size_t mCount;
shared_ptr<HandlerContext> mChild;
shared_ptr<HandlerContext<_parserElementT>> mChild;
public:
Assignment(const shared_ptr<CollectorBase> &c, size_t begin, size_t count, const shared_ptr<HandlerContext> &child)
Assignment(const shared_ptr<CollectorBase> &c, size_t begin, size_t count, const shared_ptr<HandlerContext<_parserElementT>> &child)
: mCollector(c), mBegin(begin), mCount(count), mChild(child)
{
}
void invoke(void *parent, const string &input);
void invoke(_parserElementT parent, const string &input);
};
class HandlerContext{
class HandlerContextBase{
};
template <typename _parserElementT>
class HandlerContext : public HandlerContextBase{
public:
HandlerContext(const shared_ptr<ParserHandler> &handler) :
HandlerContext(const shared_ptr<ParserHandler<_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((*it).second, begin, count, child));
mAssignments.push_back(Assignment<_parserElementT>((*it).second, begin, count, child));
}
}
void *realize(const string &input){
_parserElementT realize(const string &input){
void *ret=mHandler->invoke();
for (auto it=mAssignments.begin(); it!=mAssignments.end(); ++it){
(*it).invoke(ret,input);
}
return ret;
}
shared_ptr<HandlerContext> branch(){
shared_ptr<HandlerContext<_parserElementT>> branch(){
return make_shared<HandlerContext>(mHandler);
}
void merge(const shared_ptr<HandlerContext> &other){
void merge(const shared_ptr<HandlerContext<_parserElementT>> &other){
mAssignments.splice(mAssignments.begin(), other->mAssignments);
}
private:
shared_ptr<ParserHandler> mHandler;
list<Assignment> mAssignments;
shared_ptr<ParserHandler<_parserElementT>> mHandler;
list<Assignment<_parserElementT>> mAssignments;
};
template <typename _parserElementT>
class Parser;
class ParserContext{
class ParserContextBase{
public:
virtual shared_ptr<HandlerContextBase> beginParse(const shared_ptr<Recognizer> &rec)=0;
virtual void endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContextBase> &ctx, const string &input, size_t begin, size_t count)=0;
virtual shared_ptr<HandlerContextBase> branch()=0;
virtual void merge(const shared_ptr<HandlerContextBase> &other)=0;
virtual void removeBranch(const shared_ptr<HandlerContextBase> &other)=0;
};
template <typename _parserElementT>
class ParserContext : public ParserContextBase{
public:
ParserContext(Parser &parser);
shared_ptr<HandlerContext> beginParse(const shared_ptr<Recognizer> &rec);
void endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContext> &ctx, const string &input, size_t begin, size_t count);
shared_ptr<HandlerContext> branch();
void merge(const shared_ptr<HandlerContext> &other);
void removeBranch(const shared_ptr<HandlerContext> &other);
void *createRootObject(const string &input);
ParserContext(Parser<_parserElementT> &parser);
_parserElementT createRootObject(const string &input);
protected:
virtual shared_ptr<HandlerContextBase> beginParse(const shared_ptr<Recognizer> &rec);
virtual void endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContextBase> &ctx, const string &input, size_t begin, size_t count);
virtual shared_ptr<HandlerContextBase> branch();
virtual void merge(const shared_ptr<HandlerContextBase> &other);
virtual void removeBranch(const shared_ptr<HandlerContextBase> &other);
shared_ptr<HandlerContext<_parserElementT>> _beginParse(const shared_ptr<Recognizer> &rec);
void _endParse(const shared_ptr<Recognizer> &rec, const shared_ptr<HandlerContext<_parserElementT>> &ctx, const string &input, size_t begin, size_t count);
shared_ptr<HandlerContext<_parserElementT>> _branch();
void _merge(const shared_ptr<HandlerContext<_parserElementT>> &other);
void _removeBranch(const shared_ptr<HandlerContext<_parserElementT>> &other);
private:
Parser & mParser;
list<shared_ptr<HandlerContext>> mHandlerStack;
shared_ptr<HandlerContext> mRoot;
Parser<_parserElementT> & mParser;
list<shared_ptr<HandlerContext<_parserElementT>>> mHandlerStack;
shared_ptr<HandlerContext<_parserElementT>> mRoot;
};
template <typename _parserElementT>
class Parser{
friend class ParserContext;
friend class ParserContext<_parserElementT>;
public:
Parser(const shared_ptr<Grammar> &grammar);
shared_ptr<ParserHandler> setHandler(const string &rulename, function<void* ()> handler){
shared_ptr<ParserHandler> ret;
mHandlers[rulename]=ret=make_shared<ParserHandler>(handler);
shared_ptr<ParserHandler<_parserElementT>> setHandler(const string &rulename, function<_parserElementT ()> handler){
shared_ptr<ParserHandler<_parserElementT>> ret;
mHandlers[rulename]=ret=make_shared<ParserHandler<_parserElementT>>(handler);
return ret;
}
void * parseInput(const string &rulename, const string &input, size_t *parsed_size);
_parserElementT parseInput(const string &rulename, const string &input, size_t *parsed_size);
private:
shared_ptr<Grammar> mGrammar;
map<string, shared_ptr<ParserHandler>> mHandlers;
map<string, shared_ptr<ParserHandler<_parserElementT>>> mHandlers;
};
......
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