/*
 * NonContractingGrammar.h
 *
 * Created on: Sep 27, 2017
 * Author: Jan Travnicek
 */

#pragma once

#include <grammar/ContextSensitive/NonContractingGrammar.h>
#include <core/stringApi.hpp>

#include <grammar/GrammarFromStringLexer.h>

#include <grammar/string/common/GrammarFromStringParserCommon.h>
#include <grammar/string/common/GrammarToStringComposerCommon.h>

namespace core {

template<class SymbolType >
struct stringApi < grammar::NonContractingGrammar < SymbolType > > {
	static grammar::NonContractingGrammar < SymbolType > parse ( std::istream & input );
	static bool first ( std::istream & input );
	static void compose ( std::ostream & output, const grammar::NonContractingGrammar < SymbolType > & grammar );
};

template<class SymbolType >
grammar::NonContractingGrammar < SymbolType > stringApi < grammar::NonContractingGrammar < SymbolType > >::parse ( std::istream & input ) {
	grammar::GrammarFromStringLexer::Token token = grammar::GrammarFromStringLexer::next(input);
	if(token.type != grammar::GrammarFromStringLexer::TokenType::NON_CONTRACTING_GRAMMAR)
		throw exception::CommonException("Unrecognised NonContractingGrammar token.");

	return grammar::GrammarFromStringParserCommon::parseCSLikeGrammar < grammar::NonContractingGrammar < SymbolType > > ( input );
}

template<class SymbolType >
bool stringApi < grammar::NonContractingGrammar < SymbolType > >::first ( std::istream & input ) {
	grammar::GrammarFromStringLexer::Token token = grammar::GrammarFromStringLexer::next ( input );
	bool res = token.type == grammar::GrammarFromStringLexer::TokenType::NON_CONTRACTING_GRAMMAR;
	grammar::GrammarFromStringLexer::putback ( input, token );
	return res;
}

template<class SymbolType >
void stringApi < grammar::NonContractingGrammar < SymbolType > >::compose ( std::ostream & output, const grammar::NonContractingGrammar < SymbolType > & grammar ) {
	output << "NON_CONTRACTING_GRAMMAR";
	grammar::GrammarToStringComposerCommon::composeCSLikeGrammar ( output, grammar );
}

} /* namespace core */

