Commit c7d44a0d authored by Simon Morlat's avatar Simon Morlat

abnf recognizer works as expected

parent e5e5ec61
......@@ -41,19 +41,15 @@ void CoreRules::bit(){
}
void CoreRules::char_(){
shared_ptr<Selector> selector=make_shared<Selector>();
for(int i=0x1;i<0x7f;++i){
selector->addRecognizer(make_shared<CharRecognizer>(i));
}
addRule("char",selector);
addRule("char",Utils::char_range(0x1,0x7f));
}
void CoreRules::cr(){
addRule("cr", Foundation::charRecognizer(0x0d));
addRule("cr", Foundation::charRecognizer(0x0d,true));
}
void CoreRules::lf(){
addRule("lf",Foundation::charRecognizer(0x0a));
addRule("lf",Foundation::charRecognizer(0x0a,true));
}
void CoreRules::crlf(){
......@@ -66,7 +62,7 @@ void CoreRules::ctl(){
addRule("ctl",
Foundation::selector()
->addRecognizer(Utils::char_range(0x00, 0x1f))
->addRecognizer(Foundation::charRecognizer(0x7f))
->addRecognizer(Foundation::charRecognizer(0x7f,true))
);
}
......@@ -75,18 +71,23 @@ void CoreRules::digit(){
}
void CoreRules::dquote(){
addRule("dquote",Foundation::charRecognizer(0x22));
addRule("dquote",Foundation::charRecognizer(0x22,true));
}
void CoreRules::hexdig(){
addRule("hexdig", Foundation::selector()
->addRecognizer(getRule("digit"))
->addRecognizer(Utils::char_range('A','F'))
->addRecognizer(Foundation::charRecognizer('A'))
->addRecognizer(Foundation::charRecognizer('B'))
->addRecognizer(Foundation::charRecognizer('C'))
->addRecognizer(Foundation::charRecognizer('D'))
->addRecognizer(Foundation::charRecognizer('E'))
->addRecognizer(Foundation::charRecognizer('F'))
);
}
void CoreRules::htab(){
addRule("htab",Foundation::charRecognizer(0x09));
addRule("htab",Foundation::charRecognizer(0x09,true));
}
void CoreRules::octet(){
......@@ -94,7 +95,7 @@ void CoreRules::octet(){
}
void CoreRules::sp(){
addRule("sp",Foundation::charRecognizer(0x20));
addRule("sp",Foundation::charRecognizer(0x20,true));
}
void CoreRules::vchar(){
......@@ -150,7 +151,7 @@ ABNFGrammar::ABNFGrammar(): Grammar("ABNF"){
void ABNFGrammar::comment(){
addRule("comment", Foundation::sequence()
->addRecognizer(Foundation::charRecognizer(';'))
->addRecognizer(Foundation::charRecognizer(';',true))
->addRecognizer(
Foundation::loop()->setRecognizer(
Foundation::selector()
......
......@@ -9,16 +9,11 @@ namespace belr{
Recognizer::Recognizer(){
}
void Recognizer::reset(){
_reset();
}
void Recognizer::setName(const string& name){
mName=name;
}
size_t Recognizer::feed(const string &input, size_t pos){
cout<<"Trying rule "<<mName<<endl;
size_t match=_feed(input, pos);
if (match!=string::npos && match>0 && mName.size()>0){
string matched=input.substr(pos,match);
......@@ -27,14 +22,20 @@ size_t Recognizer::feed(const string &input, size_t pos){
return match;
}
CharRecognizer::CharRecognizer(char to_recognize) : mToRecognize(to_recognize){
}
void CharRecognizer::_reset(){
CharRecognizer::CharRecognizer(int to_recognize, bool caseSensitive) : mToRecognize(to_recognize), mCaseSensitive(caseSensitive){
if (::tolower(to_recognize)==::toupper(to_recognize)){
/*not a case caseSensitive character*/
mCaseSensitive=true;/*no need to perform a case insensitive match*/
}else if (!caseSensitive){
mToRecognize=::tolower(mToRecognize);
}
}
size_t CharRecognizer::_feed(const string &input, size_t pos){
return input[pos]==mToRecognize ? 1 : string::npos;
if (mCaseSensitive){
return input[pos]==mToRecognize ? 1 : string::npos;
}
return ::tolower(input[pos])==mToRecognize ? 1 : string::npos;
}
Selector::Selector(){
......@@ -45,20 +46,18 @@ shared_ptr<Selector> Selector::addRecognizer(const shared_ptr<Recognizer> &r){
return shared_from_this();
}
void Selector::_reset(){
for_each(mElements.begin(),mElements.end(),bind(&Recognizer::reset,placeholders::_1));
}
size_t Selector::_feed(const string &input, size_t pos){
size_t matched=0;
size_t bestmatch=0;
cout<<"Selector"<<endl;
for (auto it=mElements.begin(); it!=mElements.end(); ++it){
matched=(*it)->feed(input, pos);
if (matched!=string::npos && matched>0) break;
if (matched!=string::npos && matched>bestmatch) {
bestmatch=matched;
}
}
if (matched==string::npos || matched==0) return string::npos;
return matched;
if (bestmatch==0) return string::npos;
return bestmatch;
}
Sequence::Sequence(){
......@@ -69,15 +68,10 @@ shared_ptr<Sequence> Sequence::addRecognizer(const shared_ptr<Recognizer> &eleme
return shared_from_this();
}
void Sequence::_reset(){
for_each(mElements.begin(),mElements.end(),bind(&Recognizer::reset,placeholders::_1));
}
size_t Sequence::_feed(const string &input, size_t pos){
size_t matched=0;
size_t total=0;
cout<<"Sequence"<<endl;
for (auto it=mElements.begin(); it!=mElements.end(); ++it){
matched=(*it)->feed(input, pos);
if (matched==string::npos){
......@@ -85,7 +79,6 @@ size_t Sequence::_feed(const string &input, size_t pos){
}
pos+=matched;
total+=matched;
cout<<"Sequence: matched="<<matched<<endl;
}
return total;
}
......@@ -102,29 +95,23 @@ shared_ptr<Loop> Loop::setRecognizer(const shared_ptr<Recognizer> &element, int
return shared_from_this();
}
void Loop::_reset(){
mRecognizer.reset();
}
size_t Loop::_feed(const string &input, size_t pos){
size_t matched=0;
size_t total=0;
int repeat;
cout<<"Loop"<<endl;
for(repeat=0;mMax!=-1 ? repeat<mMax : true;repeat++){
matched=mRecognizer->feed(input,pos);
if (matched==string::npos) break;
total+=matched;
pos+=matched;
cout<<"Loop: repeat="<<repeat<<" matched="<<matched<<endl;
}
if (repeat<mMin) return string::npos;
return total;
}
shared_ptr<CharRecognizer> Foundation::charRecognizer(char character){
return make_shared<CharRecognizer>(character);
shared_ptr<CharRecognizer> Foundation::charRecognizer(int character, bool caseSensitive){
return make_shared<CharRecognizer>(character, caseSensitive);
}
shared_ptr<Selector> Foundation::selector(){
......@@ -143,7 +130,7 @@ shared_ptr<Recognizer> Utils::literal(const string & lt){
shared_ptr<Sequence> seq=Foundation::sequence();
size_t i;
for (i=0;i<lt.size();++i){
seq->addRecognizer(Foundation::charRecognizer(lt[i]));
seq->addRecognizer(Foundation::charRecognizer(lt[i],false));
}
return seq;
}
......@@ -152,7 +139,7 @@ shared_ptr<Recognizer> Utils::char_range(int begin, int end){
auto sel=Foundation::selector();
for(int i=begin; i<=end; i++){
sel->addRecognizer(
Foundation::charRecognizer((char)i)
Foundation::charRecognizer(i,true)
);
}
return sel;
......@@ -165,10 +152,6 @@ shared_ptr<Recognizer> RecognizerPointer::getPointed(){
return mRecognizer;
}
void RecognizerPointer::_reset(){
if (mRecognizer) mRecognizer->reset();
}
size_t RecognizerPointer::_feed(const string &input, size_t pos){
if (mRecognizer){
return mRecognizer->feed(input,pos);
......@@ -189,7 +172,7 @@ Grammar::Grammar(const string& name) : mName(name){
void Grammar::assignRule(const string &argname, const shared_ptr<Recognizer> &rule){
string name=toLower(argname);
string name=tolower(argname);
rule->setName(name);
auto it=mRules.find(name);
if (it!=mRules.end()){
......@@ -207,7 +190,7 @@ void Grammar::assignRule(const string &argname, const shared_ptr<Recognizer> &ru
shared_ptr<Recognizer> Grammar::getRule(const string &argname){
shared_ptr<Recognizer> ret;
string name=toLower(argname);
string name=tolower(argname);
auto it=mRules.find(name);
if (it!=mRules.end()){
shared_ptr<RecognizerPointer> pointer=dynamic_pointer_cast<RecognizerPointer>((*it).second);
......@@ -247,7 +230,7 @@ bool Grammar::isComplete()const{
return ret;
}
string Grammar::toLower(const string &str){
string tolower(const string &str){
string ret(str);
transform(ret.begin(),ret.end(), ret.begin(), ::tolower);
return ret;
......
......@@ -6,27 +6,26 @@
using namespace ::std;
namespace belr{
string tolower(const string &str);
class Recognizer{
public:
void setName(const string &name);
void reset();
size_t feed(const string &input, size_t pos);
protected:
Recognizer();
virtual void _reset()=0;
virtual size_t _feed(const string &input, size_t pos)=0;
string mName;
};
class CharRecognizer : public Recognizer{
public:
CharRecognizer(char to_recognize);
CharRecognizer(int to_recognize, bool caseSensitive=false);
private:
virtual void _reset();
virtual size_t _feed(const string &input, size_t pos);
const char mToRecognize;
int mToRecognize;
bool mCaseSensitive;
};
class Selector : public Recognizer, public enable_shared_from_this<Selector>{
......@@ -34,7 +33,6 @@ public:
Selector();
shared_ptr<Selector> addRecognizer(const shared_ptr<Recognizer> &element);
private:
virtual void _reset();
virtual size_t _feed(const string &input, size_t pos);
list<shared_ptr<Recognizer>> mElements;
};
......@@ -44,7 +42,6 @@ public:
Sequence();
shared_ptr<Sequence> addRecognizer(const shared_ptr<Recognizer> &element);
private:
virtual void _reset();
virtual size_t _feed(const string &input, size_t pos);
list<shared_ptr<Recognizer>> mElements;
};
......@@ -54,7 +51,6 @@ public:
Loop();
shared_ptr<Loop> setRecognizer(const shared_ptr<Recognizer> &element, int min=0, int max=-1);
private:
virtual void _reset();
virtual size_t _feed(const string &input, size_t pos);
shared_ptr<Recognizer> mRecognizer;
int mMin, mMax;
......@@ -63,7 +59,7 @@ private:
class Foundation{
public:
static shared_ptr<CharRecognizer> charRecognizer(char character);
static shared_ptr<CharRecognizer> charRecognizer(int character, bool caseSensitive=false);
static shared_ptr<Selector> selector();
static shared_ptr<Sequence> sequence();
static shared_ptr<Loop> loop();
......@@ -81,7 +77,6 @@ public:
shared_ptr<Recognizer> getPointed();
void setPointed(const shared_ptr<Recognizer> &r);
private:
virtual void _reset();
virtual size_t _feed(const string &input, size_t pos);
shared_ptr<Recognizer> mRecognizer;
};
......@@ -100,7 +95,6 @@ public:
private:
void assignRule(const string &name, const shared_ptr<Recognizer> &rule);
map<string,shared_ptr<Recognizer>> mRules;
string toLower(const string &str);
string mName;
};
......
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