/******************************************************************************/
/* SRD PARSER *****************************************************************/
/******************************************************************************/

#ifndef _H_EBCL_SRDPARSER
#define _H_EBCL_SRDPARSER
#include <ebcl/SRDIO.hh>
#include <ebcl/SRDParserConfig.hh>
namespace ebcl {


// T_SRDParserData - Run-time data passed to the handlers when parsing
struct T_SRDParserData
{
	// Parser configuration
	T_SRDParserConfig const& config;
	// Error output
	T_SRDErrors & errors;

	// Input list (if any) for the current rule
	RPC_SRDList input;

	// Name of the current context
	T_String currentContext;
	// Current context's data
	RP_Variant currentData;

	// Target context when entering or exiting
	T_String targetContext;
	// Data for the target context; must be initialised at entrance
	RP_Variant targetData;

	explicit T_SRDParserData(
			T_SRDParserConfig const& parser ,
			T_SRDErrors & errors );
};
M_CLASS_POINTERS( SRDParserData );

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

// E_SRDFlushMode - How the parser flushes its command list
enum class E_SRDFlushMode {
	MANUAL ,		// The parser never flushes the command list, it
				// must be done manually by calling flush()
	END ,			// Flush the command list after parsing has been
				// completed. This is the default.
	SENTENCE		// Flush after each sentence (start() and end()
				// will also cause flushes)
};


// T_SRDParser - The parser's main class
class T_SRDParser : public A_SRDReaderTarget , public A_PrivateImplementation
{
public:
	T_SRDParser( ) = delete;

	T_SRDParser( T_SRDParserConfig const& cfg );

	void start( T_SRDErrors & errors ) override;
	void push( T_SRDErrors & errors , T_SRDToken && token ) override;
	void end( T_SRDErrors & errors ) override;

	// Execute all currently queued commands
	void flush( );

	// Set/get the flush mode
	void flushMode( E_SRDFlushMode mode ) noexcept;
	E_SRDFlushMode flushMode( ) const noexcept;

	// Set/get flush token handling
	void handleFlushToken( bool handleIt ) noexcept;
	bool handleFlushToken( ) const noexcept;

	template< typename T > T const& getData( ) const;
	template< typename T > T& getData( );

private:
	T_Variant const& getExecStackTop( ) const noexcept;
	T_Variant& getExecStackTop( ) noexcept;

};
M_CLASS_POINTERS( SRDParser );

template< typename T >
inline T const& T_SRDParser::getData( ) const
{
	return getExecStackTop( ).value< T >( );
}

template< typename T >
inline T& T_SRDParser::getData( )
{
	return getExecStackTop( ).value< T >( );
}


} // namespace
#endif // _H_EBCL_SRDPARSER