/*
 * AutomatonToStringComposerCommon.h
 *
 * Created on: Sep 26, 2017
 * Author: Jan Travnicek
 */

#ifndef AUTOMATON_FROM_STRING_PARSER_COMMON_H_
#define AUTOMATON_FROM_STRING_PARSER_COMMON_H_

#include <exception>

#include <alib/istream>

#include <automaton/AutomatonFromStringLexer.h>
#include <core/stringApi.hpp>

namespace automaton {

struct AutomatonFromStringParserCommon {
	static void initialFinalState(std::istream& input, bool& rightArrow, bool& leftArrow);

	template < class Type >
	static ext::vector < Type > parseList ( std::istream & input );
};

template < class Type >
ext::vector<Type> AutomatonFromStringParserCommon::parseList (std::istream& input) {
	ext::vector<Type> res;

	automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next(input);
	if(token.type != automaton::AutomatonFromStringLexer::TokenType::LEFT_BRACKET) {
		throw exception::CommonException("Expected LEFT_BRACKET token.");
	}

	token = automaton::AutomatonFromStringLexer::next(input);
	if(token.type != automaton::AutomatonFromStringLexer::TokenType::RIGHT_BRACKET) {
		automaton::AutomatonFromStringLexer::putback(input, token);
		while(true) {
			Type symbol = core::stringApi<Type>::parse(input);
			res.push_back(symbol);

			token = automaton::AutomatonFromStringLexer::next(input);
			if(token.type == automaton::AutomatonFromStringLexer::TokenType::RIGHT_BRACKET) {
				break;
			}
			if(token.type != automaton::AutomatonFromStringLexer::TokenType::COMMA) {
				throw exception::CommonException("Expected RIGHT_BRACKET or COMMA token");
			}
		}
	}

	if(token.type != automaton::AutomatonFromStringLexer::TokenType::RIGHT_BRACKET) {
		throw exception::CommonException("Expected RIGHT_BRACKET token");
	}

	return res;
}

} /* namespace automaton */

#endif /* AUTOMATON_FROM_STRING_PARSER_COMMON_H_ */
