/******************************************************************************/
/* SRD - PARSER CONFIGURATION *************************************************/
/******************************************************************************/

#ifndef _H_EBCL_SRDPARSERCONFIG
#define _H_EBCL_SRDPARSERCONFIG
#include <ebcl/SRDDefinitions.hh>
#include <ebcl/Types.hh>
namespace ebcl {


/*= PROCESSED PARSER CONFIGURATION ===========================================*/

// E_SRDTransitionType - Type of a parser state transition
enum class E_SRDTransitionType {
	WORD ,
	ENUM ,
	TOKEN
};

// T_SRDTransition - A parser transition (condition + next state)
struct T_SRDTransition
{
	// Match type
	E_SRDTransitionType type;

	// Match value: word or enum index, or token type.
	union {
		uint32_t index;
		E_SRDTokenType tokenType;
	};

	// Next state
	uint32_t next;

	T_SRDTransition( E_SRDTokenType tokenType , uint32_t next );
	T_SRDTransition( E_SRDTransitionType type , uint32_t index , uint32_t next );
};

/*----------------------------------------------------------------------------*/

// T_SRDParserConfig - Parser configuration
struct T_SRDParserConfig
{
	enum : uint32_t { INVALID_END = 0xffffffff };

	F_SRDHandler onStart;
	F_SRDHandler onFinish;

	T_Array< T_SRDContext > contexts;
	T_ObjectTable< T_String , T_SRDEnum > enums;

	// Index of words used in the rules
	T_HashIndex wordsIndex;
	T_Array< T_String > words;

	// Start indices for the contexts' automatons
	T_Array< uint32_t > startStates;

	// End states. Either 0xffffffff for states that are not end states,
	// or the rule ID for valid end states.
	T_Array< uint32_t > endStates;

	// State transitions
	T_MultiArray< T_SRDTransition > transitions;

	// Rule contexts
	T_MultiArray< uint32_t > ruleContexts;

	T_SRDParserConfig( ) = delete;
	T_SRDParserConfig( T_SRDParserDefs const& defs );

	// Try to find a transition matching the token
	bool transition( uint32_t& state , T_SRDToken const& token ) const;

	// Find the value of an enumeration member
	T_Optional< uint32_t > enumValue( char const* name , T_String const& member ) const noexcept;
	T_Optional< uint32_t > enumValue( T_String const& name , T_String const& member ) const noexcept;
};
M_CLASS_POINTERS( SRDParserConfig );

/*----------------------------------------------------------------------------*/

// X_SRDParserConfig - Exception indicating that definitions were incorrect
class X_SRDParserConfig : public std::exception
{
   private:
	T_Buffer< char > errorString_;

   public:
	explicit X_SRDParserConfig( T_StringBuilder const& error );
	explicit X_SRDParserConfig( T_String const& error );
	char const * what( ) const noexcept override;
};


} // namespace
#include <ebcl/inline/SRDParserConfig.hh>
#endif // _H_EBCL_SRDPARSERCONFIG