#ifndef INC_TreeParser_hpp__
#define INC_TreeParser_hpp__

/**
 * <b>SOFTWARE RIGHTS</b>
 * <p>
 * ANTLR 2.6.0 MageLang Insitute, 1999
 * <p>
 * We reserve no legal rights to the ANTLR--it is fully in the
 * public domain. An individual or company may do whatever
 * they wish with source code distributed with ANTLR or the
 * code generated by ANTLR, including the incorporation of
 * ANTLR, or its output, into commerical software.
 * <p>
 * We encourage users to develop software with ANTLR. However,
 * we do ask that credit is given to us for developing
 * ANTLR. By "credit", we mean that if you use ANTLR or
 * incorporate any source code into one of your programs
 * (commercial product, research project, or otherwise) that
 * you acknowledge this fact somewhere in the documentation,
 * research report, etc... If you like ANTLR and have
 * developed a nice tool with the output, please mention that
 * you developed it using ANTLR. In addition, we ask that the
 * headers remain intact in our source code. As long as these
 * guidelines are kept, we expect to continue enhancing this
 * system and expect to make other tools available as they are
 * completed.
 * <p>
 * The ANTLR gang:
 * @version ANTLR 2.6.0 MageLang Insitute, 1999
 * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
 * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
 * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
 */
#include "antlr/config.hpp"
#include "antlr/AST.hpp"
#include "antlr/ASTFactory.hpp"
#include "antlr/BitSet.hpp"
#include "antlr/RecognitionException.hpp"
#include "antlr/TreeParserSharedInputState.hpp"

ANTLR_BEGIN_NAMESPACE(antlr)

class TreeParser {
public:
	TreeParser();
	TreeParser(const TreeParserSharedInputState& state);
	virtual ~TreeParser();

protected:
	void setTokenNames(const char** tokenNames_);

public:
	/** The AST Null object; the parsing cursor is set to this when
	 *  it is found to be null.  This way, we can test the
	 *  token type of a node without having to have tests for null
	 *  everywhere.
	 */
	static RefAST ASTNULL;

protected:
	/** Where did this rule leave off parsing; avoids a return parameter */
	RefAST _retTree;

	/** guessing nesting level; guessing==0 implies not guessing */
	// int guessing; // = 0;

	/** Nesting level of registered handlers */
	// int exceptionLevel; // = 0;

	TreeParserSharedInputState inputState;

	/** Table of token type to token names */
	ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string> tokenNames;

	/** AST return value for a rule is squirreled away here */
	RefAST returnAST;

	/** AST support code; parser and treeparser delegate to this object */
	ASTFactory astFactory; // = new ASTFactory();

	/** Used to keep track of indent depth with -traceTreeParser */
	int traceDepth;

public:
	/** Get the AST return value squirreled away in the parser */
	RefAST getAST() const {
		return returnAST;
	}

	ANTLR_USE_NAMESPACE(std)string getTokenName(int num) const;
	ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string> getTokenNames() const;

protected:
	void match(RefAST t, int ttype);

public:
	/**Make sure current lookahead symbol matches the given set
	 * Throw an exception upon mismatch, which is catch by either the
	 * error handler or by the syntactic predicate.
	 */
	void match(RefAST t, const BitSet& b);

protected:
	void matchNot(RefAST t, int ttype);

public:
	static void panic();

	/** Parser error-reporting function can be overridden in subclass */
	virtual void reportError(const RecognitionException& ex);

	/** Parser error-reporting function can be overridden in subclass */
	virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s);

	/** Parser warning-reporting function can be overridden in subclass */
	virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s);

	/** Specify an object with support code (shared by
	 *  Parser and TreeParser.  Normally, the programmer
	 *  does not play with this, using setASTNodeType instead.
	 */
//	void setASTFactory(ASTFactory f);

	/** Specify the type of node to create during tree building */
	void setASTNodeFactory(ASTFactory::factory_type factory);

protected:
	/** Utility class which allows tracing to work even when exceptions are
	 * thrown.
	 */
	class Tracer {
	private:
		TreeParser* parser;
		ANTLR_USE_NAMESPACE(std)string text;
		RefAST tree;
	public:
		Tracer(TreeParser* p,const ANTLR_USE_NAMESPACE(std)string& t, RefAST a)
			: parser(p), text(t), tree(a) { parser->traceIn(text,tree); }
		~Tracer()
			{ parser->traceOut(text,tree); }
	private:
		Tracer(const Tracer&);							// undefined
		const Tracer& operator=(const Tracer&);	// undefined
	};

public:
	void traceIndent();
	void traceIn(const ANTLR_USE_NAMESPACE(std)string& rname, RefAST t);
	void traceOut(const ANTLR_USE_NAMESPACE(std)string& rname, RefAST t);

private:
	TreeParser(const TreeParser& other);
	TreeParser& operator=(const TreeParser& other);
};

ANTLR_END_NAMESPACE

#endif //INC_TreeParser_hpp__
