/*
* grammarbuilder.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef _GRAMMARBUILDER_H_
#define _GRAMMARBUILDER_H_
#include "parser.h"
// =============================================================================
namespace belr{
class ABNFAlternation;
class ABNFBuilder{
public:
virtual ~ABNFBuilder() = default;
virtual std::shared_ptr buildRecognizer(const std::shared_ptr &grammar)=0;
};
class ABNFRule : public ABNFBuilder{
public:
static std::shared_ptr create();
void setName(const std::string &name);
void setDefinedAs(const std::string &defined_as);
void setAlternation(const std::shared_ptr &a);
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
bool isExtension()const;
const std::string &getName()const{
return mName;
}
private:
std::shared_ptr mAlternation;
std::string mName;
std::string mDefinedAs;
};
class ABNFRuleList : public ABNFBuilder{
public:
static std::shared_ptr create();
void addRule(const std::shared_ptr & rule);
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
private:
std::list> mRules;
};
class ABNFNumval : public ABNFBuilder{
public:
static std::shared_ptr create();
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
void setDecVal(const std::string &decval);
void setHexVal(const std::string &hexval);
void setBinVal(const std::string &binval);
private:
void parseValues(const std::string &val, int base);
std::vector mValues;
bool mIsRange = false;
};
class ABNFElement : public ABNFBuilder{
public:
static std::shared_ptr create();
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
void setElement(const std::shared_ptr &e);
void setRulename(const std::string &rulename);
void setCharVal(const std::string &charval);
void setProseVal(const std::string &prose);
private:
std::shared_ptr mElement;
std::string mRulename;
std::string mCharVal;
};
class ABNFGroup : public ABNFBuilder{
public:
static std::shared_ptr create();
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
void setAlternation(const std::shared_ptr &a);
private:
std::shared_ptr mAlternation;
};
class ABNFRepetition : public ABNFBuilder{
public:
static std::shared_ptr create();
void setRepeat(const std::string &r);
void setMin(int min);
void setMax(int max);
void setCount(int count);
void setElement(const std::shared_ptr &e);
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
private:
int mMin = 0;
int mMax = -1;
int mCount = -1;
std::string mRepeat;
std::shared_ptr mElement;
};
class ABNFOption : public ABNFBuilder{
public:
static std::shared_ptr create();
void setAlternation(const std::shared_ptr &a);
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
private:
std::shared_ptr mAlternation;
};
class ABNFConcatenation : public ABNFBuilder{
public:
static std::shared_ptr create();
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
void addRepetition(const std::shared_ptr &r);
private:
std::list> mRepetitions;
};
class ABNFAlternation : public ABNFBuilder{
public:
static std::shared_ptr create();
void addConcatenation(const std::shared_ptr &c);
std::shared_ptr buildRecognizer(const std::shared_ptr &grammar);
std::shared_ptr buildRecognizerNoOptim(const std::shared_ptr &grammar);
private:
std::list> mConcatenations;
};
/**
* The ABNFGrammarBuilder builds a Grammar object from an ABNF grammar defined in a text file.
**/
class ABNFGrammarBuilder{
public:
/**
* Initialize the builder.
**/
BELR_PUBLIC ABNFGrammarBuilder();
/**
* Create a grammar from an ABNF grammar defined in the string pointed by abnf.
* 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 abnf the string that contains the abnf grammar.
* @param grammar an optional grammar to include.
* @return the Grammar object corresponding to the text definition loaded, nullptr if an error occured.
**/
BELR_PUBLIC std::shared_ptr createFromAbnf(const std::string &abnf, const std::shared_ptr &grammar=nullptr);
/**
* 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, nullptr if an error occured.
**/
BELR_PUBLIC std::shared_ptr createFromAbnfFile(const std::string &path, const std::shared_ptr &grammar=nullptr);
private:
Parser> mParser;
};
}
#endif