Commit e5e5ec61 authored by Simon Morlat's avatar Simon Morlat

work in progress

parent 7b3235e3
SUBDIRS=src
SUBDIRS=src tests
#!/bin/sh
if ! type aclocal-$AM_VERSION 1>/dev/null 2>&1; then
# automake-1.10 (recommended) is not available on Fedora 8
AUTOMAKE=automake
ACLOCAL=aclocal
else
ACLOCAL=aclocal-${AM_VERSION}
AUTOMAKE=automake-${AM_VERSION}
fi
if test -f /opt/local/bin/glibtoolize ; then
# darwin
LIBTOOLIZE=/opt/local/bin/glibtoolize
else
LIBTOOLIZE=libtoolize
fi
if test -d /opt/local/share/aclocal ; then
ACLOCAL_ARGS="-I /opt/local/share/aclocal"
fi
if test -d /share/aclocal ; then
ACLOCAL_ARGS="-I /share/aclocal"
fi
echo "Generating build scripts in myantlr..."
set -x
$LIBTOOLIZE --copy --force
$ACLOCAL $ACLOCAL_ARGS
autoheader
$AUTOMAKE --force-missing --add-missing --copy
autoconf
......@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([myantlr], [0.0.1], [simon.morlat@linphone.org])
AC_CONFIG_SRCDIR([src/myantlr.hh])
AC_INIT([belr], [0.0.1], [simon.morlat@linphone.org])
AC_CONFIG_SRCDIR([src/belr.hh])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
......@@ -13,7 +13,7 @@ AC_PROG_LIBTOOL
# Checks for programs.
AC_PROG_CXX
CXXFLAGS="$CXXFLAGS -std=c++11"
CXXFLAGS="$CXXFLAGS -std=c++11 -Wall -Werror"
# Checks for libraries.
......@@ -26,6 +26,7 @@ AC_TYPE_SSIZE_T
AC_CONFIG_FILES(
Makefile
src/Makefile
tests/Makefile
)
AC_OUTPUT
lib_LTLIBRARIES=libmyantlr.la
lib_LTLIBRARIES=libbelr.la
libmyantlr_la_SOURCES=myantlr.cc myantlr.hh
libbelr_la_SOURCES=belr.cc belr.hh \
abnf.cc abnf.hh
This diff is collapsed.
#include "belr.hh"
namespace belr{
/*
* Core definitions of ABNF
**/
class CoreRules : public Grammar{
public:
CoreRules();
private:
void alpha();
void bit();
void char_();
void cr();
void lf();
void crlf();
void ctl();
void digit();
void dquote();
void hexdig();
void htab();
void lwsp();
void octet();
void sp();
void vchar();
void wsp();
};
class ABNFGrammar : public Grammar{
public:
ABNFGrammar();
private:
void comment();
void c_nl();
void c_wsp();
void rulename();
void repeat();
void defined_as();
void rulelist();
void rule();
void elements();
void alternation();
void concatenation();
void repetition();
void element();
void group();
void option();
void char_val();
void num_val();
void prose_val();
void bin_val();
void dec_val();
void hex_val();
};
}//end of namespace
#include "belr.hh"
#include <algorithm>
#include <iostream>
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);
cout<<"Matched recognizer '"<<mName<<"' with sequence '"<<matched<<"'."<<endl;
}
return match;
}
CharRecognizer::CharRecognizer(char to_recognize) : mToRecognize(to_recognize){
}
void CharRecognizer::_reset(){
}
size_t CharRecognizer::_feed(const string &input, size_t pos){
return input[pos]==mToRecognize ? 1 : string::npos;
}
Selector::Selector(){
}
shared_ptr<Selector> Selector::addRecognizer(const shared_ptr<Recognizer> &r){
mElements.push_back(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;
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==0) return string::npos;
return matched;
}
Sequence::Sequence(){
}
shared_ptr<Sequence> Sequence::addRecognizer(const shared_ptr<Recognizer> &element){
mElements.push_back(element);
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){
return string::npos;
}
pos+=matched;
total+=matched;
cout<<"Sequence: matched="<<matched<<endl;
}
return total;
}
Loop::Loop(){
mMin=0;
mMax=-1;
}
shared_ptr<Loop> Loop::setRecognizer(const shared_ptr<Recognizer> &element, int min, int max){
mMin=min;
mMax=max;
mRecognizer=element;
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<Selector> Foundation::selector(){
return make_shared<Selector>();
}
shared_ptr<Sequence> Foundation::sequence(){
return make_shared<Sequence>();
}
shared_ptr<Loop> Foundation::loop(){
return make_shared<Loop>();
}
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]));
}
return seq;
}
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)
);
}
return sel;
}
RecognizerPointer::RecognizerPointer() : mRecognizer(NULL){
}
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);
}else{
cerr<<"RecognizerPointer is undefined"<<endl;
abort();
}
return string::npos;
}
void RecognizerPointer::setPointed(const shared_ptr<Recognizer> &r){
mRecognizer=r;
}
Grammar::Grammar(const string& name) : mName(name){
}
void Grammar::assignRule(const string &argname, const shared_ptr<Recognizer> &rule){
string name=toLower(argname);
rule->setName(name);
auto it=mRules.find(name);
if (it!=mRules.end()){
shared_ptr<RecognizerPointer> pointer=dynamic_pointer_cast<RecognizerPointer>((*it).second);
if (pointer){
pointer->setPointed(rule);
}else{
cerr<<"Error: rule '"<<name<<"' is being redefined !"<<endl;
abort();
}
}else{
mRules[name]=rule;
}
}
shared_ptr<Recognizer> Grammar::getRule(const string &argname){
shared_ptr<Recognizer> ret;
string name=toLower(argname);
auto it=mRules.find(name);
if (it!=mRules.end()){
shared_ptr<RecognizerPointer> pointer=dynamic_pointer_cast<RecognizerPointer>((*it).second);
if (pointer){
if (pointer->getPointed()){/*if pointer is defined return the pointed value directly*/
return pointer->getPointed();
}else{
return pointer;
}
}
return (*it).second;
}else{/*the rule doesn't exist yet: return a pointer*/
ret=make_shared<RecognizerPointer>();
mRules[name]=ret;
}
return ret;
}
void Grammar::include(const shared_ptr<Grammar>& grammar){
for(auto it=grammar->mRules.begin();it!=grammar->mRules.end();++it){
if (mRules.find((*it).first)!=mRules.end()){
cerr<<"Rule '"<<(*it).first<<"' is being redefined while including grammar '"<<grammar->mName<<"' into '"<<mName<<"'"<<endl;
}
mRules[(*it).first]=(*it).second;
}
}
bool Grammar::isComplete()const{
bool ret=true;
for(auto it=mRules.begin(); it!=mRules.end(); ++it){
shared_ptr<RecognizerPointer> pointer=dynamic_pointer_cast<RecognizerPointer>((*it).second);
if (pointer && !pointer->getPointed()){
cerr<<"Rule '"<<(*it).first<<"' is not defined."<<endl;
ret=false;
}
}
return ret;
}
string Grammar::toLower(const string &str){
string ret(str);
transform(ret.begin(),ret.end(), ret.begin(), ::tolower);
return ret;
}
}
#include <list>
#include <map>
#include <memory>
using namespace ::std;
namespace belr{
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);
private:
virtual void _reset();
virtual size_t _feed(const string &input, size_t pos);
const char mToRecognize;
};
class Selector : public Recognizer, public enable_shared_from_this<Selector>{
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;
};
class Sequence : public Recognizer, public enable_shared_from_this<Sequence>{
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;
};
class Loop : public Recognizer, public enable_shared_from_this<Loop>{
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;
};
class Foundation{
public:
static shared_ptr<CharRecognizer> charRecognizer(char character);
static shared_ptr<Selector> selector();
static shared_ptr<Sequence> sequence();
static shared_ptr<Loop> loop();
};
class Utils{
public:
static shared_ptr<Recognizer> literal(const string & lt);
static shared_ptr<Recognizer> char_range(int begin, int end);
};
class RecognizerPointer : public Recognizer{
public:
RecognizerPointer();
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;
};
class Grammar{
public:
Grammar(const string &name);
void include(const shared_ptr<Grammar>& grammar);
template <typename _recognizerT>
shared_ptr<_recognizerT> addRule(const string & name, const shared_ptr<_recognizerT> &rule){
assignRule(name, rule);
return rule;
}
shared_ptr<Recognizer> getRule(const string &name);
bool isComplete()const;
private:
void assignRule(const string &name, const shared_ptr<Recognizer> &rule);
map<string,shared_ptr<Recognizer>> mRules;
string toLower(const string &str);
string mName;
};
}
#include "myantlr.hh"
#include <algorithm>
namespace myantlr{
Recognizer::Recognizer(){
mMatchCount=0;
}
void Recognizer::reset(){
_reset();
mMatchCount=0;
}
ssize_t Recognizer::feed(const string &input, ssize_t pos){
mMatchCount=_feed(input, pos);
return mMatchCount;
}
CharRecognizer::CharRecognizer(char to_recognize) : mToRecognize(to_recognize){
}
void CharRecognizer::_reset(){
}
ssize_t CharRecognizer::_feed(const string &input, ssize_t pos){
return input[pos]==mToRecognize ? 1 : 0;
}
Selector::Selector(){
}
void Selector::addRecognizer(const shared_ptr<Recognizer> &r){
mElements.push_back(r);
}
void Selector::_reset(){
for_each(mElements.begin(),mElements.end(),bind(&Recognizer::reset,placeholders::_1));
}
ssize_t Selector::_feed(const string &input, ssize_t pos){
ssize_t matched=0;
for (auto it=mElements.begin(); it!=mElements.end(); ++it){
matched=(*it)->feed(input, pos);
if (matched>0) break;
}
return matched;
}
}
\ No newline at end of file
#include <list>
#include <memory>
using namespace ::std;
namespace myantlr{
class Recognizer{
public:
void reset();
ssize_t feed(const string &input, ssize_t pos);
protected:
Recognizer();
virtual void _reset()=0;
virtual ssize_t _feed(const string &input, ssize_t pos)=0;
ssize_t mMatchCount;
};
class CharRecognizer : public Recognizer{
public:
CharRecognizer(char to_recognize);
private:
virtual void _reset();
virtual ssize_t _feed(const string &input, ssize_t pos);
const char mToRecognize;
};
class Selector : public Recognizer{
public:
Selector();
void addRecognizer(const shared_ptr<Recognizer> &element);
private:
virtual void _reset();
virtual ssize_t _feed(const string &input, ssize_t pos);
list<shared_ptr<Recognizer>> mElements;
};
}
noinst_PROGRAMS=parse_grammar
parse_grammar_SOURCES=parse_grammar.cc
parse_grammar_LDADD=$(top_builddir)/src/libbelr.la
AM_CPPFLAGS=-I$(top_srcdir)/src
#include "abnf.hh"
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
using namespace::belr;
int main(int argc, char *argv[]){
const char *grammarfile;
int fd;
struct stat sb;
char *grammar;
shared_ptr<Recognizer> parser;
if (argc<2){
cerr<<argv[0]<< "grammarfile-to-load"<<endl;
return -1;
}
grammarfile=argv[1];
if (stat(grammarfile,&sb)==-1){
cerr<<"Could not stat "<<grammarfile<<endl;
return -1;
}
fd=open(grammarfile,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 "<<grammarfile<<endl;
return -1;
}
cout<<"Building ABNF recognizer"<<endl;
ABNFGrammar abnf_grammar;
if (!abnf_grammar.isComplete()){
cerr<<"ABNF Grammar not complete, aborting."<<endl;
return -1;
}
parser=abnf_grammar.getRule("rulelist");
cout<<"Finished ABNF recognizer construction, starting parsing"<<endl;
string sgrammar(grammar);
parser->feed(sgrammar,0);
cout<<"parsing done"<<endl;
delete []grammar;
return 0;
};
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