Commit b3e58896 authored by Simon Morlat's avatar Simon Morlat

fix bug with child reported to parent erroneously under untracked rules.

parent 18c52ead
......@@ -21,7 +21,7 @@ const string &Recognizer::getName()const{
size_t Recognizer::feed(const shared_ptr<ParserContextBase> &ctx, const string &input, size_t pos){
size_t match;
shared_ptr<HandlerContextBase> hctx=ctx->beginParse(shared_from_this());
ParserLocalContext hctx=ctx->beginParse(shared_from_this());
match=_feed(ctx, input, pos);
if (match!=string::npos && match>0){
if (0 && mName.size()>0){
......@@ -29,7 +29,7 @@ size_t Recognizer::feed(const shared_ptr<ParserContextBase> &ctx, const string &
cout<<"Matched recognizer '"<<mName<<"' with sequence '"<<matched<<"'."<<endl;
}
}
ctx->endParse(shared_from_this(), hctx, input, pos, match);
ctx->endParse(hctx, input, pos, match);
return match;
}
......@@ -142,6 +142,7 @@ size_t Loop::_feed(const shared_ptr<ParserContextBase> &ctx, const string &input
if (matched==string::npos) break;
total+=matched;
pos+=matched;
if (input[pos]=='\0') break;
}
if (repeat<mMin) return string::npos;
return total;
......
......@@ -2,6 +2,8 @@
#include "parser.hh"
#include <iostream>
#include <algorithm>
#include <chrono>
#include <ctime>
namespace belr{
......@@ -79,29 +81,42 @@ ParserContext<_parserElementT>::ParserContext(Parser<_parserElementT> &parser) :
}
template <typename _parserElementT>
shared_ptr<HandlerContext<_parserElementT>> ParserContext<_parserElementT>::_beginParse(const shared_ptr<Recognizer> &rec){
shared_ptr<HandlerContext<_parserElementT>> ctx;
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(ctx);
mHandlerStack.push_back(static_pointer_cast<HandlerContext<_parserElementT>>(ctx));
}else{
isBranch=true;
ctx=branch();
}
return ctx;
return ParserLocalContext(ctx,rec,isBranch);
}
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){
void ParserContext<_parserElementT>::_endParse(const ParserLocalContext &localctx, const string &input, size_t begin, size_t count){
if (!localctx.mIsBranch){
mHandlerStack.pop_back();
}
if (count!=string::npos && count>0){
if (!mHandlerStack.empty()){
/*assign object to parent */
mHandlerStack.back()->setChild(rec->getName(), begin, count, ctx);
if (count!=string::npos && count>0){
if (!mHandlerStack.empty()){
/*assign object to parent */
mHandlerStack.back()->setChild(localctx.mRecognizer->getName(), begin, count,
static_pointer_cast<HandlerContext< _parserElementT >> (localctx.mHandlerContext));
}else{
/*no parent, this is our root object*/
mRoot=static_pointer_cast<HandlerContext< _parserElementT >>(localctx.mHandlerContext);
}
}
}else{
if (count!=string::npos && count>0){
merge(localctx.mHandlerContext);
/*assign string to parent */
mHandlerStack.back()->setChild(localctx.mRecognizer->getName(), begin, count, NULL);
}else{
/*no parent, this is our root object*/
mRoot=ctx;
removeBranch(localctx.mHandlerContext);
}
}
}
......@@ -144,18 +159,18 @@ void ParserContext<_parserElementT>::_removeBranch(const shared_ptr<HandlerConte
}
template <typename _parserElementT>
shared_ptr<HandlerContextBase> ParserContext<_parserElementT>::beginParse(const shared_ptr<Recognizer> &rec){
return static_pointer_cast<HandlerContext<_parserElementT>>(_beginParse(rec));
ParserLocalContext ParserContext<_parserElementT>::beginParse(const shared_ptr<Recognizer> &rec){
return _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);
void ParserContext<_parserElementT>::endParse(const ParserLocalContext &localctx, const string &input, size_t begin, size_t count){
_endParse(localctx, input, begin, count);
}
template <typename _parserElementT>
shared_ptr<HandlerContextBase> ParserContext<_parserElementT>::branch(){
return static_pointer_cast<HandlerContext<_parserElementT>>(_branch());
return _branch();
}
template <typename _parserElementT>
......@@ -187,9 +202,13 @@ _parserElementT Parser<_parserElementT>::parseInput(const string &rulename, cons
shared_ptr<Recognizer> rec=mGrammar->getRule(rulename);
auto pctx=make_shared<ParserContext<_parserElementT>>(*this);
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;
if (parsed_size) *parsed_size=parsed;
return pctx->createRootObject(input);
auto ret= pctx->createRootObject(input);
return ret;
}
}
......@@ -127,8 +127,21 @@ public:
return make_shared<HandlerContext>(mHandler);
}
void merge(const shared_ptr<HandlerContext<_parserElementT>> &other){
mAssignments.splice(mAssignments.begin(), other->mAssignments);
mAssignments.splice(mAssignments.end(), other->mAssignments);
}
typename list<Assignment<_parserElementT>>::iterator getLastIterator(){
if (mAssignments.empty())
return mAssignments.end();
return --mAssignments.end();
}
void undoAssignments(const typename list<Assignment<_parserElementT>>::iterator &last_valid){
if (mAssignments.end()==last_valid){
mAssignments.clear();
}else{
mAssignments.erase(++last_valid,mAssignments.end());
}
}
private:
shared_ptr<ParserHandlerBase<_parserElementT>> mHandler;
list<Assignment<_parserElementT>> mAssignments;
......@@ -137,10 +150,19 @@ private:
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){
}
shared_ptr<HandlerContextBase> mHandlerContext;
shared_ptr<Recognizer> mRecognizer;
bool mIsBranch;
};
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 ParserLocalContext beginParse(const shared_ptr<Recognizer> &rec)=0;
virtual void endParse(const ParserLocalContext &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;
......@@ -152,13 +174,13 @@ public:
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 ParserLocalContext beginParse(const shared_ptr<Recognizer> &rec);
virtual void endParse(const ParserLocalContext &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);
ParserLocalContext _beginParse(const shared_ptr<Recognizer> &rec);
void _endParse(const ParserLocalContext &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);
......
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
From: "Charlie" <sip:smorlat2@78.220.48.77>;tag=HW3X1aviU
To: marie <sip:smorlat2@siptest.linphone.org>
CSeq: 21 REGISTER
Call-ID: s69J2OQ4h4
Max-Forwards: 70
......
......@@ -77,9 +77,10 @@ password = *( unreserved / escaped /
hostport = host [ ":" port ]
host = hostname / IPv4address / IPv6reference
hostname = *( domainlabel "." ) toplabel [ "." ]
domainlabel = alphanum
/ alphanum *( alphanum / "-" ) alphanum
toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum
;domainlabel is modified to avoid an ambiguity
domainlabel = alphanum / (alphanum *( alphanum / ( *("-") alphanum) ) )
;toplabel is modified to avoid an ambiguity
toplabel = ALPHA / (ALPHA *( alphanum / (*("-") alphanum ) ) )
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
IPv6reference = "[" IPv6address "]"
......
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