Commit 99313a25 authored by Simon Morlat's avatar Simon Morlat

reorganize source files so that they headers can be included by applications

parent 8c4cabc6
......@@ -8,7 +8,7 @@ AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
AM_SILENT_RULES(yes)
LT_INIT(disable-shared win32-dll)
LT_INIT(disable-static win32-dll)
# Checks for programs.
AC_PROG_CXX
......
......@@ -3,12 +3,13 @@
namespace belr{
/*
* Core definitions of ABNF
/**
* Grammar containing core definitions of ABNF.
* This is required for almost all IETF text based protocols.
**/
class CoreRules : public Grammar{
public:
///Initialize a CoreRules grammar object.
CoreRules();
private:
void alpha();
......
......@@ -17,7 +17,8 @@ class ParserContextBase;
struct TransitionMap{
TransitionMap();
bool intersect(const TransitionMap *other);
void merge(const TransitionMap *other);
bool intersect(const TransitionMap *other, TransitionMap *result); //performs a AND operation
void merge(const TransitionMap *other); //Performs an OR operation
bool mPossibleChars[256];
};
......@@ -145,11 +146,25 @@ private:
shared_ptr<Recognizer> mRecognizer;
};
/**
* Grammar class represents an ABNF grammar, with all its rules.
**/
class Grammar{
public:
/**
* Initialize an empty grammar, giving a name for debugging.
**/
Grammar(const string &name);
/**
* Include another grammar into this grammar.
**/
void include(const shared_ptr<Grammar>& grammar);
/* the grammar takes ownership of the recognizer, which must not be used outside of this grammar.
/**
* Add arule to the grammar.
* @param name the name of the rule
* @param rule the rule recognier, must be an instance of belr::Recognizer.
* @return the rule (the recognizer). The recognizer is given the name of the rule.
* @note The grammar takes ownership of the recognizer, which must not be used outside of this grammar.
* TODO: use unique_ptr to enforce this, or make a copy ?
**/
template <typename _recognizerT>
......@@ -157,18 +172,48 @@ public:
assignRule(name, rule);
return rule;
}
/**
* Extend a rule from the grammar.
* This corresponds to the '/=' operator of ABNF definition.
* @param name the name of the rule to extend.
* @param rule the recognizer of the extension.
* @return the rule.
**/
template <typename _recognizerT>
shared_ptr<_recognizerT> extendRule(const string & name, const shared_ptr<_recognizerT> &rule){
_extendRule(name, rule);
return rule;
}
/**
* Find a rule from the grammar, given its name.
* @param name the name of the rule
* @return the recognizer implementing this rule. Is NULL if the rule doesn't exist in the grammar.
**/
shared_ptr<Recognizer> findRule(const string &name);
/*
* getRule() never returns NULL. If the rule is not (yet) defined, it returns an undefined pointer, that will be set later if the rule gets defined.
/**
* Find a rule from the grammar, given its name.
* Unlike findRule(), getRule() never returns NULL.
* If the rule is not (yet) defined, it returns an undefined pointer, that will be set later if the rule gets defined.
* This mechanism is required to allow defining rules in any order, and defining rules that call themselve recursively.
* @param name the name of the rule to get
* @return the recognizer implementing the rule, or a RecognizerPointer if the rule isn't yet defined.
**/
shared_ptr<Recognizer> getRule(const string &name);
/**
* Returns true if the grammar is complete, that is all rules are defined.
* In other words, a grammar is complete if no rule depends on another rule which is not defined.
**/
bool isComplete()const;
/**
* Optimize the grammar. This is required to obtain good performance of the recognizers implementing the rule.
* The optimization step consists in checking whether belr::Selector objects in the grammar are exclusive or not.
* A selector is said exclusive when a single sub-rule can match. Knowing this in advance optimizes the processing because no branch
* context is to be created to explore the different choices of the selector recognizer.
**/
void optimize();
/**
* Return the number of rules in this grammar.
**/
int getNumRules()const;
private:
void assignRule(const string &name, const shared_ptr<Recognizer> &rule);
......
......@@ -121,10 +121,25 @@ private:
list<shared_ptr<ABNFConcatenation>> mConcatenations;
};
/**
* The ABNFGrammarBuilder builds a Grammar object from an ABNF grammar defined in a text file.
**/
class ABNFGrammarBuilder{
public:
/**
* Initialize the builder.
**/
ABNFGrammarBuilder();
/**
* Create a grammar from an ABNF grammar defined in the text file pointed by path.
* An optional Grammar argument corresponding to a grammar to include can be passed.
* Usually the belr::CoreRules grammar is required for most IETF text protocols.
* The returned grammar can be used to instanciate a belr::Parser object capable of parsing
* the protocol or language described in the grammar.
* @param path the path from where to load the abnf definition.
* @param grammar an optional grammar to include.
* @return the Grammar object corresponding to the text definition loaded, NULL if an error occured.
**/
shared_ptr<Grammar> createFromAbnf(const string &path, const shared_ptr<Grammar> &grammar=NULL);
private:
Parser<shared_ptr<ABNFBuilder>> mParser;
......
......@@ -181,6 +181,13 @@ private:
shared_ptr<HandlerContext<_parserElementT>> mRoot;
};
/**
* Parser class.
* This template class allows to parse a text input using a Grammar object describing the language of the input to be parsed.
* The template argument _parserElementT must be a base class for all elements that will be created to represent the result of the parsing.
* This can be 'void*' if the parser is implemented in C, but can also be any C++ class provided that each type representing a parsed entity
* inherits from this class.
**/
template <typename _parserElementT>
class Parser{
friend class ParserContext<_parserElementT>;
......
......@@ -6,3 +6,5 @@ libbelr_la_SOURCES=belr.cc belr.hh \
parser.cc parser.hh \
grammarbuilder.cc grammarbuilder.hh
AM_CPPFLAGS=-I$(top_srcdir)/include
#include "abnf.hh"
#include "belr/abnf.hh"
namespace belr{
......
#include "belr.hh"
#include "parser.hh"
#include "belr/belr.hh"
#include "belr/parser.hh"
#include <algorithm>
#include <iostream>
......@@ -19,6 +19,16 @@ bool TransitionMap::intersect(const TransitionMap* other){
return false;
}
bool TransitionMap::intersect(const TransitionMap *other, TransitionMap *result){
bool ret=false;
for(size_t i=0;i<sizeof(mPossibleChars)/sizeof(bool);++i){
bool tmp=mPossibleChars[i] && other->mPossibleChars[i];
result->mPossibleChars[i]=tmp;
if (tmp) ret=true;
}
return ret;
}
void TransitionMap::merge(const TransitionMap* other){
for(size_t i=0;i<sizeof(mPossibleChars)/sizeof(bool);++i){
if (other->mPossibleChars[i]) mPossibleChars[i]=true;
......
#include "abnf.hh"
#include "grammarbuilder.hh"
#include "belr/abnf.hh"
#include "belr/grammarbuilder.hh"
#include "parser-impl.cc"
#include <iostream>
......
#include "parser.hh"
#include "belr/parser.hh"
#include <iostream>
#include <algorithm>
#include <chrono>
......
#include <parser.hh>
#include <belr/parser.hh>
#include <iostream>
#include "parser-impl.cc"
......
......@@ -4,4 +4,4 @@ belr_parse_SOURCES=belrparse.cc
belr_parse_LDADD=$(top_builddir)/src/libbelr.la
AM_CPPFLAGS=-I$(top_srcdir)/src
AM_CPPFLAGS=-I$(top_srcdir)/include
#include "grammarbuilder.hh"
#include "abnf.hh"
#include "belr/grammarbuilder.hh"
#include "belr/abnf.hh"
#include <iostream>
#include <fstream>
#include <sstream>
......@@ -18,7 +18,8 @@ int main(int argc, char *argv[]){
int i;
int repeat_count=1;
if (argc<2){
cerr<<argv[0]<< " [--repeat <count>] <grammarfile-to-load> [<input file>] [rule1] [rule2]..."<<endl;
cerr<<argv[0]<< " [--repeat <count>] <grammarfile-to-load> - test an abnf and instanciate the parser"<<endl;
cerr<<argv[0]<< " [--repeat <count>] <grammarfile-to-load> <input file to parse> <entry rule> [rule1] [rule2]..."<<endl;
return -1;
}
for(i=1;i<argc;++i){
......
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