/*
 * AutomatonFromXMLParser.h
 *
 *  Created on: Oct 12, 2013
 *      Author: Martin Zak
 */

#ifndef AUTOMATON_FROM_XML_PARSER_H_
#define AUTOMATON_FROM_XML_PARSER_H_

#include <alib/deque>
#include <alib/set>
#include <alib/vector>
#include <alib/map>

#include <sax/FromXMLParserHelper.h>
#include <sax/ParserException.h>
#include <core/xmlApi.hpp>

#include <regexp/xml/UnboundedRegExpStructure.h>
#include <alphabet/xml/RankedSymbol.h>
#include <automaton/common/Shift.h>
#include <common/xml/SymbolOrEpsilon.h>

namespace automaton {

/**
 * Parser used to get general FSM or EpsilonNFA, NFA, DFA from XML parsed into deque of Tokens.
 */
class AutomatonFromXMLParser {
public:
	template<class T>
	static void parseTransitions(ext::deque<sax::Token>::iterator& input, T& automaton);

	template < class StateType >
	static ext::set<StateType> parseStates(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseInputAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseCallInputAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseReturnInputAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseLocalInputAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseRankedInputAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parsePushdownStoreAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseInitialPushdownStoreSymbols(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static SymbolType parseInitialPushdownStoreSymbol(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseOutputAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::set<SymbolType> parseTapeAlphabet(ext::deque<sax::Token>::iterator& input);
	template < class StateType >
	static StateType parseInitialState(ext::deque<sax::Token>::iterator& input);
	template < class StateType >
	static ext::set<StateType> parseInitialStates(ext::deque<sax::Token>::iterator& input);
	template < class StateType >
	static ext::set<StateType> parseFinalStates(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static SymbolType parseBlankSymbol(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static SymbolType parseBottomOfTheStackSymbol(ext::deque<sax::Token>::iterator& input);
	template < class InputSymbolType, class PushdownStoreSymbolType >
	static ext::map<InputSymbolType, ext::pair<ext::vector<PushdownStoreSymbolType>, ext::vector<PushdownStoreSymbolType> > > parseInputToPushdownStoreOperation(ext::deque<sax::Token>::iterator& input);

	template < class StateType >
	static StateType parseTransitionFrom(ext::deque<sax::Token>::iterator& input);
	template < class StateType >
	static ext::vector<StateType> parseTransitionFromMultiple(ext::deque<sax::Token>::iterator& input);
	template < class StateType >
	static StateType parseTransitionTo(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::vector<SymbolType> parseTransitionPop(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static SymbolType parseTransitionSinglePop(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::vector<SymbolType> parseTransitionPush(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static SymbolType parseTransitionSinglePush(ext::deque<sax::Token>::iterator& input);

	template < class SymbolType >
	static SymbolType parseTransitionInputSymbol(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::vector<SymbolType> parseTransitionInputSymbolMultiple(ext::deque<sax::Token>::iterator& input);

	template < class SymbolType >
	static SymbolType parseTransitionOutputSymbol(ext::deque<sax::Token>::iterator& input);
	template < class SymbolType >
	static ext::vector<SymbolType> parseTransitionOutputSymbolMultiple(ext::deque<sax::Token>::iterator& input);

	static Shift parseTransitionShift(ext::deque<sax::Token>::iterator& input) {
		Shift shift;

		sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "shift" );

		if ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::CHARACTER, "left" ) )
			shift = Shift::LEFT;
		else if ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::CHARACTER, "right" ) )
			shift = Shift::RIGHT;
		else if ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::CHARACTER, "none" ) )
			shift = Shift::NONE;
		else
			throw sax::ParserException ( sax::Token ( "", sax::Token::TokenType::CHARACTER ), * input );

		++input;
		sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "shift" );

		return shift;
	}

	template < class SymbolType >
	static regexp::UnboundedRegExpStructure < SymbolType > parseTransitionInputRegexp(ext::deque<sax::Token>::iterator& input);
};

template<class T>
void AutomatonFromXMLParser::parseTransitions(ext::deque<sax::Token>::iterator& input, T& automaton) {
	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, "transitions");
	while (sax::FromXMLParserHelper::isTokenType(input, sax::Token::TokenType::START_ELEMENT)) {
		core::xmlApi < T >::parseTransition(input, automaton);
	}
	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "transitions");
}

template < class StateType >
ext::set < StateType > AutomatonFromXMLParser::parseStates ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < StateType > states;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "states" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		states.insert ( core::xmlApi < StateType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "states" );
	return states;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseCallInputAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > inputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "callInputAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		inputSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "callInputAlphabet" );
	return inputSymbols;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseReturnInputAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > inputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "returnInputAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		inputSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "returnInputAlphabet" );
	return inputSymbols;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseLocalInputAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > inputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "localInputAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		inputSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "localInputAlphabet" );
	return inputSymbols;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseInputAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > inputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "inputAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		inputSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "inputAlphabet" );
	return inputSymbols;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseRankedInputAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > inputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "rankedInputAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		inputSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "rankedInputAlphabet" );
	return inputSymbols;
}

template < class StateType >
StateType AutomatonFromXMLParser::parseInitialState ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "initialState" );
	StateType state ( core::xmlApi < StateType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "initialState" );

	return state;
}

template < class StateType >
ext::set < StateType > AutomatonFromXMLParser::parseInitialStates ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < StateType > initialStates;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "initialStates" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		initialStates.insert ( core::xmlApi < StateType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "initialStates" );
	return initialStates;
}

template < class StateType >
ext::set < StateType > AutomatonFromXMLParser::parseFinalStates ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < StateType > finalStates;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "finalStates" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		finalStates.insert ( core::xmlApi < StateType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "finalStates" );
	return finalStates;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parsePushdownStoreAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > stackSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "pushdownStoreAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		stackSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "pushdownStoreAlphabet" );
	return stackSymbols;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseInitialPushdownStoreSymbols ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > initialSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "initialPushdownStoreSymbols" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		initialSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "initialPushdownStoreSymbols" );
	return initialSymbols;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseOutputAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > outputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "outputAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		outputSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "outputAlphabet" );
	return outputSymbols;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseInitialPushdownStoreSymbol ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "initialPushdownStoreSymbol" );
	SymbolType initialSymbol ( core::xmlApi < SymbolType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "initialPushdownStoreSymbol" );

	return initialSymbol;
}

template < class SymbolType >
ext::set < SymbolType > AutomatonFromXMLParser::parseTapeAlphabet ( ext::deque < sax::Token >::iterator & input ) {
	ext::set < SymbolType > tapeSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "tapeAlphabet" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		tapeSymbols.insert ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "tapeAlphabet" );
	return tapeSymbols;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseBlankSymbol ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "blankSymbol" );
	SymbolType blank ( core::xmlApi < SymbolType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "blankSymbol" );

	return blank;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseBottomOfTheStackSymbol ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "bottomOfTheStackSymbol" );
	SymbolType blank ( core::xmlApi < SymbolType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "bottomOfTheStackSymbol" );

	return blank;
}

template < class InputSymbolType, class PushdownStoreSymbolType >
ext::map < InputSymbolType, ext::pair < ext::vector < PushdownStoreSymbolType >, ext::vector < PushdownStoreSymbolType > > > AutomatonFromXMLParser::parseInputToPushdownStoreOperation ( ext::deque < sax::Token >::iterator & input ) {
	ext::map < InputSymbolType, ext::pair < ext::vector < PushdownStoreSymbolType >, ext::vector < PushdownStoreSymbolType > > > operations;

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "inputToPushdownStoreOperations" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) ) {
		sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "operation" );

		InputSymbolType inputSymbol ( core::xmlApi < InputSymbolType >::parse ( input ) );

		ext::vector < PushdownStoreSymbolType > pop  = parseTransitionPop < PushdownStoreSymbolType > ( input );
		ext::vector < PushdownStoreSymbolType > push = parseTransitionPush < PushdownStoreSymbolType > ( input );

		operations.insert ( std::move ( inputSymbol ), ext::make_pair ( std::move ( pop ), std::move ( push ) ) );

		sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "operation" );
	}

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "inputToPushdownStoreOperations" );
	return operations;
}

template < class StateType >
StateType AutomatonFromXMLParser::parseTransitionTo ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "to" );
	StateType state ( core::xmlApi < StateType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "to" );

	return state;
}

template < class StateType >
StateType AutomatonFromXMLParser::parseTransitionFrom ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "from" );
	StateType state ( core::xmlApi < StateType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "from" );

	return state;
}

template < class StateType >
ext::vector < StateType > AutomatonFromXMLParser::parseTransitionFromMultiple ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "from" );
	ext::vector < StateType > states;

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		states.push_back ( core::xmlApi < StateType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "from" );
	return states;
}

template < class SymbolType >
ext::vector < SymbolType > AutomatonFromXMLParser::parseTransitionPop ( ext::deque < sax::Token >::iterator & input ) {
	ext::vector < SymbolType > pops;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "pop" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		pops.push_back ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "pop" );
	return pops;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseTransitionSinglePop ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "pop" );
	SymbolType pop = core::xmlApi < SymbolType >::parse ( input );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "pop" );

	return pop;
}

template < class SymbolType >
ext::vector < SymbolType > AutomatonFromXMLParser::parseTransitionPush ( ext::deque < sax::Token >::iterator & input ) {
	ext::vector < SymbolType > pushes;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "push" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		pushes.push_back ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "push" );
	return pushes;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseTransitionSinglePush ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "push" );
	SymbolType push = core::xmlApi < SymbolType >::parse ( input );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "push" );

	return push;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseTransitionInputSymbol ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "input" );
	SymbolType result ( core::xmlApi < SymbolType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "input" );

	return result;
}

template < class SymbolType >
SymbolType AutomatonFromXMLParser::parseTransitionOutputSymbol ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "output" );
	SymbolType result ( core::xmlApi < SymbolType >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "output" );

	return result;
}

template < class SymbolType >
ext::vector < SymbolType > AutomatonFromXMLParser::parseTransitionInputSymbolMultiple ( ext::deque < sax::Token >::iterator & input ) {
	ext::vector < SymbolType > inputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "input" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		inputSymbols.push_back ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "input" );
	return inputSymbols;
}

template < class SymbolType >
ext::vector < SymbolType > AutomatonFromXMLParser::parseTransitionOutputSymbolMultiple ( ext::deque < sax::Token >::iterator & input ) {
	ext::vector < SymbolType > outputSymbols;
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "output" );

	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) )
		outputSymbols.push_back ( core::xmlApi < SymbolType >::parse ( input ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "output" );
	return outputSymbols;
}

template < class SymbolType >
regexp::UnboundedRegExpStructure < SymbolType > AutomatonFromXMLParser::parseTransitionInputRegexp ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "input" );
	regexp::UnboundedRegExpStructure < SymbolType > result ( core::xmlApi < regexp::UnboundedRegExpStructure < SymbolType > >::parse ( input ) );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "input" );

	return result;
}

} /* namespace automaton */

#endif /* AUTOMATON_FROM_XML_PARSER_H_ */

