#ifndef LIBWCCL_PARSER_PARSER_H
#define LIBWCCL_PARSER_PARSER_H

#include <iostream>

// ----------------------------------------------------------------------------
#include <sstream>

// ----------------------------------------------------------------------------
#include <libcorpus2/tagset.h>

// ----------------------------------------------------------------------------
#include <libwccl/variables.h>
#include <libwccl/values/strset.h>
#include <libwccl/ops/operator.h>

// rules
#include <libwccl/ops/rulesequence.h>

// exceptions
#include <libwccl/parser/ParserException.h>

// ----------------------------------------------------------------------------

namespace Wccl{

class Parser {
public:
	Parser(const Corpus2::Tagset&);
	~Parser();

	// ---------------------------------------------------------------------------
	// methods for parsing string operators
	boost::shared_ptr<Operator<StrSet> >
			parseStringOperator(const std::string&) const;
	boost::shared_ptr<Operator<StrSet> >
			parseStringOperator(std::istream&) const;

	// ---------------------------------------------------------------------------
	// methods for parsing bool operators
	boost::shared_ptr<Operator<Bool> >
			parseBoolOperator(const std::string&) const;
	boost::shared_ptr<Operator<Bool> >
			parseBoolOperator(std::istream&) const;

	// ---------------------------------------------------------------------------
	// methods for parsing bool operators
	boost::shared_ptr<Operator<TSet> >
			parseSymSetOperator(const std::string&) const;
	boost::shared_ptr<Operator<TSet> >
			parseSymSetOperator(std::istream&) const;

	// ---------------------------------------------------------------------------
	// methods for parsing position operators
	boost::shared_ptr<Operator<Position> >
			parsePositionOperator(const std::string&) const;
	boost::shared_ptr<Operator<Position> >
			parsePositionOperator(std::istream&) const;

	// ---------------------------------------------------------------------------
	// methods for parsing any operators
	boost::shared_ptr<FunctionalOperator>
			parseAnyOperator(const std::string&) const;
	boost::shared_ptr<FunctionalOperator>
			parseAnyOperator(std::istream&) const;

	// ---------------------------------------------------------------------------
	// Parsing rule sequence from input string
	boost::shared_ptr<RuleSequence>
			parseRuleSequence(const std::string&) const;
	boost::shared_ptr<RuleSequence>
			parseRuleSequence(std::istream&) const;

	// ---------------------------------------------------------------------------
	// Parsing single rule from input string
	boost::shared_ptr<TagRule>
			parseSingleRule(const std::string&) const;
	boost::shared_ptr<TagRule>
			parseSingleRule(std::istream&) const;

	// ---------------------------------------------------------------------------
	const Corpus2::Tagset& tagset() const {
		return tagset_;
	}

private:
	const Corpus2::Tagset &tagset_;
};

} // end Wccl ns

#endif // LIBWCCL_PARSER_PARSER_H