Commit 3fa50687 authored by Simon Morlat's avatar Simon Morlat

works perfectly

parent a2fd02d6
......@@ -24,7 +24,7 @@ size_t Recognizer::feed(const shared_ptr<ParserContextBase> &ctx, const string &
shared_ptr<HandlerContextBase> hctx=ctx->beginParse(shared_from_this());
match=_feed(ctx, input, pos);
if (match!=string::npos && match>0){
if (1 && mName.size()>0){
if (0 && mName.size()>0){
string matched=input.substr(pos,match);
cout<<"Matched recognizer '"<<mName<<"' with sequence '"<<matched<<"'."<<endl;
}
......@@ -196,7 +196,7 @@ size_t RecognizerPointer::_feed(const shared_ptr<ParserContextBase> &ctx, const
if (mRecognizer){
return mRecognizer->feed(ctx, input, pos);
}else{
cerr<<"RecognizerPointer is undefined"<<endl;
cerr<<"RecognizerPointer with name '"<<mName<<"' is undefined"<<endl;
abort();
}
return string::npos;
......@@ -262,6 +262,7 @@ shared_ptr<Recognizer> Grammar::getRule(const string &argname){
return (*it).second;
}else{/*the rule doesn't exist yet: return a pointer*/
ret=make_shared<RecognizerPointer>();
ret->setName(string("@")+name);
mRules[name]=ret;
}
return ret;
......
......@@ -4,12 +4,8 @@
#include "parser-impl.cc"
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <fstream>
#include <sstream>
namespace belr{
......@@ -56,17 +52,14 @@ void ABNFNumval::parseValues(const string &val, int base){
}
void ABNFNumval::setDecVal(const string& decval){
cout<<"setDecVal "<<decval<<endl;
parseValues(decval,10);
}
void ABNFNumval::setHexVal(const string& hexval){
cout<<"setHexVal "<<hexval<<endl;
parseValues(hexval,16);
}
void ABNFNumval::setBinVal(const string& binval){
cout<<"setBinVal "<<binval<<endl;
parseValues(binval,2);
}
......@@ -154,7 +147,7 @@ void ABNFRepetition::setRepeat(const string& r){
shared_ptr< Recognizer > ABNFRepetition::buildRecognizer(const shared_ptr< Grammar >& grammar){
if (mRepeat.empty()) return mElement->buildRecognizer(grammar);
cout<<"Building repetition recognizer with count="<<mCount<<" min="<<mMin<<" max="<<mMax<<endl;
//cout<<"Building repetition recognizer with count="<<mCount<<" min="<<mMin<<" max="<<mMax<<endl;
if (mCount!=-1){
return Foundation::loop()->setRecognizer(mElement->buildRecognizer(grammar), mCount, mCount);
}else{
......@@ -204,7 +197,7 @@ shared_ptr<ABNFAlternation> ABNFAlternation::create(){
}
void ABNFAlternation::addConcatenation(const shared_ptr<ABNFConcatenation> &c){
cout<<"Concatenation "<<c<<" added to alternation "<<this<<endl;
//cout<<"Concatenation "<<c<<" added to alternation "<<this<<endl;
mConcatenations.push_back(c);
}
......@@ -223,19 +216,18 @@ shared_ptr< Recognizer > ABNFAlternation::buildRecognizerNoOptim(const shared_pt
shared_ptr<ABNFRule> ABNFRule::create(){
cout<<"Rule created."<<endl;
return make_shared<ABNFRule>();
}
void ABNFRule::setName(const string& name){
if (!mName.empty())
cerr<<"Rule "<<this<<" is renamed !!!!!"<<endl;
cout<<"Rule "<<this<<" is named "<<name<<endl;
//cout<<"Rule "<<this<<" is named "<<name<<endl;
mName=name;
}
void ABNFRule::setAlternation(const shared_ptr<ABNFAlternation> &a){
cout<<"Rule "<<this<<" is given alternation "<<a<<endl;
//cout<<"Rule "<<this<<" is given alternation "<<a<<endl;
mAlternation=a;
}
......@@ -253,12 +245,12 @@ void ABNFRule::setDefinedAs(const string& defined_as){
shared_ptr<ABNFRuleList> ABNFRuleList::create(){
cout<<"Rulelist created."<<endl;
//cout<<"Rulelist created."<<endl;
return make_shared<ABNFRuleList>();
}
void ABNFRuleList::addRule(const shared_ptr<ABNFRule>& rule){
cout<<"Rule "<<rule<<" added to rulelist "<<this<<endl;
//cout<<"Rule "<<rule<<" added to rulelist "<<this<<endl;
mRules.push_back(rule);
}
......@@ -309,34 +301,27 @@ ABNFGrammarBuilder::ABNFGrammarBuilder()
->setCollector("dec-val", make_sfn(&ABNFNumval::setDecVal));
}
shared_ptr<Grammar> ABNFGrammarBuilder::createFromAbnf(const string &path){
struct stat sb;
char *grammar;
shared_ptr<Grammar> ABNFGrammarBuilder::createFromAbnf(const string &path, const shared_ptr<Grammar> &gram){
size_t parsed;
if (stat(path.c_str(),&sb)==-1){
cerr<<"Could not stat "<<path<<endl;
return NULL;
}
int fd=open(path.c_str(),O_RDONLY);
grammar=new char[sb.st_size+1];
grammar[sb.st_size]='\0';
if (read(fd,grammar,sb.st_size)!=sb.st_size){
cerr<<"Could not read "<<path<<endl;
close(fd);
ifstream istr(path);
if (!istr.is_open()){
cerr<<"Could not open "<<path<<endl;
return NULL;
}
string sgrammar(grammar);
delete []grammar;
shared_ptr<ABNFBuilder> builder = mParser.parseInput("rulelist",sgrammar,&parsed);
if (parsed<(size_t)sb.st_size){
cerr<<"ERROR: only "<<parsed<<" bytes parsed over a total of "<< sb.st_size <<endl;
stringstream sstr;
sstr<<istr.rdbuf();
shared_ptr<ABNFBuilder> builder = mParser.parseInput("rulelist",sstr.str(),&parsed);
if (parsed<(size_t)sstr.str().size()){
cerr<<"ERROR: only "<<parsed<<" bytes parsed over a total of "<< sstr.str().size() <<endl;
return NULL;
}
shared_ptr<Grammar> gram=make_shared<Grammar>(path);
builder->buildRecognizer(gram);
cout<<"Succesfully created grammar with "<<gram->getNumRules()<<" rules."<<endl;
if (gram->isComplete()){
shared_ptr<Grammar> retGram;
if (gram==NULL) retGram=make_shared<Grammar>(path);
else retGram=gram;
builder->buildRecognizer(retGram);
cout<<"Succesfully created grammar with "<<retGram->getNumRules()<<" rules."<<endl;
if (retGram->isComplete()){
cout<<"Grammar is complete."<<endl;
}else{
cout<<"WARNING: grammar is not complete."<<endl;
......
......@@ -125,7 +125,7 @@ private:
class ABNFGrammarBuilder{
public:
ABNFGrammarBuilder();
shared_ptr<Grammar> createFromAbnf(const string &path);
shared_ptr<Grammar> createFromAbnf(const string &path, const shared_ptr<Grammar> &grammar=NULL);
private:
Parser<shared_ptr<ABNFBuilder>> mParser;
};
......
......@@ -44,7 +44,7 @@ void ParserChildCollector<_derivedParserElementT,_parserElementT, _valueT>::invo
template <typename _parserElementT>
void Assignment<_parserElementT>::invoke(_parserElementT parent, const string &input){
if (mChild){
mCollector->invokeWithChild(parent, mChild->realize(input));
mCollector->invokeWithChild(parent, mChild->realize(input,mBegin,mCount));
}else{
string value=input.substr(mBegin, mCount);
shared_ptr<CollectorBase<_parserElementT,const string&>> cc1=dynamic_pointer_cast<CollectorBase<_parserElementT,const string&>>(mCollector);
......@@ -66,8 +66,12 @@ void Assignment<_parserElementT>::invoke(_parserElementT parent, const string &i
}
template <typename _derivedParserElementT, typename _parserElementT>
_parserElementT ParserHandler<_derivedParserElementT,_parserElementT>::invoke(){
return universal_pointer_cast<_parserElementT>(mHandlerCreateFunc());
_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 NULL;
}
template <typename _parserElementT>
......@@ -104,11 +108,14 @@ void ParserContext<_parserElementT>::_endParse(const shared_ptr<Recognizer> &rec
template <typename _parserElementT>
_parserElementT ParserContext<_parserElementT>::createRootObject(const string &input){
return mRoot ? mRoot->realize(input) : NULL;
return mRoot ? mRoot->realize(input,0,input.size()) : NULL;
}
template <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> ParserContext<_parserElementT>::_branch(){
if (mHandlerStack.empty()){
cerr<<"Cannot branch while stack is empty"<<endl;
}
shared_ptr<HandlerContext<_parserElementT>> ret=mHandlerStack.back()->branch();
mHandlerStack.push_back(ret);
return ret;
......
......@@ -2,6 +2,7 @@
#include <parser.hh>
#include <iostream>
#include "parser-impl.cc"
namespace belr{
......@@ -9,6 +10,59 @@ namespace belr{
HandlerContextBase::~HandlerContextBase(){
}
DebugElement::DebugElement(const string& rulename, const string& value)
:mRulename(rulename), mValue(value){
}
shared_ptr< DebugElement > DebugElement::create(const string& rulename, const string& value){
return make_shared<DebugElement>(rulename,value);
}
void DebugElement::addChild(const shared_ptr< DebugElement >& e){
//cout<<mRulename<<"["<<this<<"] is given child "<<e->mRulename<<"["<<e<<"]"<<endl;
mChildren.push_back(e);
}
ostream& DebugElement::tostream(int level, ostream& str) const{
int i;
for(i=0;i<level;i++) str<<'\t';
if (!mChildren.empty()){
str<<mRulename<<endl;
for (auto it=mChildren.begin(); it!=mChildren.end(); ++it){
(*it)->tostream(level+1,str);
}
}else{
size_t pos;
string value(mValue);
while((pos=value.find("\r"))!=string::npos){
value.replace(pos,1,"\\r");
};
while((pos=value.find("\n"))!=string::npos){
value.replace(pos,1,"\\n");
};
str<<mRulename<<" : "<<"'"<<value<<"'"<<endl;
}
return str;
}
DebugParser::DebugParser(const shared_ptr< Grammar >& grammar)
: Parser<shared_ptr<DebugElement>>(grammar){
}
shared_ptr<DebugElement> DebugParser::parseInput(const string& rulename, const string& input, size_t* parsed_size){
return Parser<shared_ptr<DebugElement>>::parseInput(rulename, input, parsed_size);
}
void DebugParser::setObservedRules(const list< string >& rules){
for (auto it=rules.begin(); it!=rules.end(); ++it){
auto h=setHandler(*it, make_fn(&DebugElement::create));
for (auto it2=rules.begin(); it2!=rules.end(); ++it2){
h->setCollector(*it2, make_sfn(&DebugElement::addChild));
}
}
}
}//end of namespace
\ No newline at end of file
}//end of namespace
......@@ -49,7 +49,7 @@ template <typename _parserElementT>
class ParserHandlerBase : public enable_shared_from_this<ParserHandlerBase<_parserElementT>>{
friend class HandlerContext<_parserElementT>;
public:
virtual _parserElementT invoke()=0;
virtual _parserElementT invoke(const string &input, size_t begin, size_t count)=0;
shared_ptr<HandlerContext<_parserElementT>> createContext();
protected:
map<string, shared_ptr<AbstractCollector<_parserElementT>> > mCollectors;
......@@ -61,22 +61,27 @@ public:
ParserHandler(const function<_derivedParserElementT ()> &create)
: mHandlerCreateFunc(create){
}
ParserHandler(const string &rulename, const function<_derivedParserElementT (const string &, const string &)> &create)
: mHandlerCreateDebugFunc(create), mRulename(rulename){
}
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setCollector(const string &child_rule_name, function<void (_derivedParserElementT , const string & )> fn){
this->mCollectors[child_rule_name]=make_shared<ParserCollector<_derivedParserElementT,_parserElementT,const string&>>(fn);
this->mCollectors[tolower(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[child_rule_name]=make_shared<ParserCollector<_derivedParserElementT,_parserElementT,int>>(fn);
this->mCollectors[tolower(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[child_rule_name]=make_shared<ParserChildCollector<_derivedParserElementT,_parserElementT,_valueT>>(fn);
this->mCollectors[tolower(child_rule_name)]=make_shared<ParserChildCollector<_derivedParserElementT,_parserElementT,_valueT>>(fn);
return static_pointer_cast<ParserHandler<_derivedParserElementT,_parserElementT>>(this->shared_from_this());
}
_parserElementT invoke();
_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>
......@@ -111,8 +116,8 @@ public:
mAssignments.push_back(Assignment<_parserElementT>((*it).second, begin, count, child));
}
}
_parserElementT realize(const string &input){
_parserElementT ret=mHandler->invoke();
_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);
}
......@@ -171,7 +176,16 @@ public:
template <typename _derivedParserElementT>
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> setHandler(const string &rulename,const function<_derivedParserElementT ()> & handler){
shared_ptr<ParserHandler<_derivedParserElementT,_parserElementT>> ret;
mHandlers[rulename]=ret=make_shared<ParserHandler<_derivedParserElementT,_parserElementT>>(handler);
mHandlers[tolower(rulename)]=ret=make_shared<ParserHandler<_derivedParserElementT,_parserElementT>>(handler);
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);
return ret;
}
......@@ -181,15 +195,35 @@ private:
map<string, shared_ptr<ParserHandlerBase<_parserElementT>>> mHandlers;
};
class DebugElement{
public:
DebugElement(const string &rulename, const string &value);
static shared_ptr<DebugElement> create(const string &rulename, const string &value);
void addChild(const shared_ptr<DebugElement> &e);
ostream &tostream(int level, ostream &str)const;
private:
string mRulename;
string mValue;
list<shared_ptr<DebugElement>> mChildren;
};
class DebugParser : protected Parser<shared_ptr<DebugElement>>{
public:
DebugParser(const shared_ptr<Grammar> &grammar);
void setObservedRules(const list<string> &rules);
shared_ptr<DebugElement> parseInput(const string &rulename, const string &input, size_t *parsed_size);
};
template <typename _retT>
function< _retT ()> make_fn(_retT (*arg)()){
return function<_retT ()>(arg);
}
template <typename _arg1T, typename _arg2T>
function< void (_arg1T,_arg2T)> make_fn(void (*arg)(_arg1T,_arg2T)){
return function< void (_arg1T,_arg2T)>(arg);
template <typename _retT, typename _arg1T, typename _arg2T>
function< _retT (_arg1T,_arg2T)> make_fn(_retT (*arg)(_arg1T,_arg2T)){
return function< _retT (_arg1T,_arg2T)>(arg);
}
template <typename _klassT, typename _argT>
......
......@@ -2,19 +2,55 @@
#include "grammarbuilder.hh"
#include "abnf.hh"
#include <iostream>
#include <fstream>
#include <sstream>
#include <chrono>
#include <ctime>
using namespace::belr;
int main(int argc, char *argv[]){
if (argc<2){
cerr<<argv[0]<< " <grammarfile-to-load>"<<endl;
cerr<<argv[0]<< " <grammarfile-to-load> [<input file>] [rule1] [rule2]..."<<endl;
return -1;
}
ABNFGrammarBuilder builder;
builder.createFromAbnf(argv[1]);
shared_ptr<Grammar> grammar=make_shared<Grammar>(argv[1]);
grammar->include(make_shared<CoreRules>());
builder.createFromAbnf(argv[1],grammar);
if (argc>3){
ifstream istr(argv[2]);
if (!istr.is_open()){
cerr<<"Could not open "<<argv[2]<<endl;
return -1;
}
stringstream str;
str<<istr.rdbuf();
DebugParser parser(grammar);
list<string> rules;
for(int i=3; i<argc; ++i){
rules.push_back(argv[i]);
}
parser.setObservedRules(rules);
size_t parsed;
auto t_start = std::chrono::high_resolution_clock::now();
auto ret=parser.parseInput(argv[3],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;
}
if (ret){
ret->tostream(0,cout);
}else{
cerr<<"Parsing failed."<<endl;
return -1;
}
}
return 0;
};
REGISTER sip:siptest.linphone.org SIP/2.0
Via: SIP/2.0/TLS 192.168.0.25:41076;alias;branch=z9hG4bK.m-SPAXXd3;rport
From: <sip:smorlat2@siptest.linphone.org>;tag=HW3X1aviU
To: sip:smorlat2@siptest.linphone.org
CSeq: 21 REGISTER
Call-ID: s69J2OQ4h4
Max-Forwards: 70
Supported: outbound
Contact: <sip:smorlat2@78.220.48.77:41076;transport=tls>;+sip.instance="<urn:uuid:2d839989-0bf2-49ba-80b7-2146037f729a>"
Expires: 3600
User-Agent: Linphone/3.7.0 (belle-sip/1.3.3)
Content-Length: 0
Authorization: Digest realm="siptest.linphone.org", nonce="f5Zb2AAAAABXkU1AAAD253sZEAsAAAAA", algorithm=MD5, opaque="+GNywA==", username="smorlat2", uri="sip:siptest.linphone.org", response="f86327204e4c826f47d761c9ad3afdb3", cnonce="faaa9595", nc=00000001, qop=auth
SIP/2.0 403 Forbidden
Via: SIP/2.0/TLS 192.168.0.25:41076;alias;branch=z9hG4bK.m-SPAXXd3;rport=41076;received=78.220.48.77
From: <sip:smorlat2@siptest.linphone.org>;tag=HW3X1aviU
To: <sip:smorlat2@siptest.linphone.org>;tag=yDXec8ej8Hrea
Call-ID: s69J2OQ4h4
CSeq: 21 REGISTER
Server: Flexisip/0.8.0 (sofia-sip-nta/2.0)
Content-Length: 0
This diff is collapsed.
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