#ifndef INC_XPathParser_hpp_
#define INC_XPathParser_hpp_

#include <antlr/config.hpp>
/* $ANTLR 2.7.2: "XPathParser.g" -> "XPathParser.hpp"$ */
#include <antlr/TokenStream.hpp>
#include <antlr/TokenBuffer.hpp>
#include "XPathParserTokenTypes.hpp"
#include <antlr/LLkParser.hpp>

#line 16 "XPathParser.g"

	#include "dbxml/XmlPortability.hpp"
	#include "dbxml/XmlException.hpp"
	#include <sstream>
	#include <vector>
	#include <cmath>
	#include "QueryContext.hpp"

	using namespace antlr;
	using namespace DbXml;

	// The ParserContext is passed through the production rules
	// as the XPath expression is passed. The context contains
	// a number of state variables so that the rules can be
	// smart about where their productions appear in the
	// expression.
	//
	class Step
	{
	public:
		Step(const std::string &axis, const std::string &name)
		 : axis_(axis), name_(name)
		{
		}
		std::string axis_;
		std::string name_;
	};
	class StepStack
	{
	public:
		StepStack()
		 : top_(0)
		{
			v_.reserve(16);
		}
		void push(const Step &n)
		{
			if (top_ == v_.size()) {
				v_.push_back(n);
				++top_;
			} else {
				v_[top_]= n;
				++top_;
			}
		}
		void pop()
		{
			if (top_ != 0) {
				--top_;
			}
		}
		bool empty() const
		{
			return top_==0;
		}
		const Step &top(size_t n= 0) const
		{
			return v_[top_-1-n];
		}
		const size_t size() const
		{
			return top_;
		}
	private:
		std::vector<Step> v_; // The most recent step node test.
		size_t top_;
	};
	class ParserContext
	{
	public:
		ParserContext()
		{
		}
		void push_step(const std::string &a, const std::string &n)
		{
			steps_.push(Step(a, n));
		}
		void pop_step(size_t n=1)
		{
			for(;n>0;--n)
				steps_.pop();
		}
		const std::string step() const
		{
			std::string r;
			if(
				steps_.size()>=3 &&
				steps_.top(0).axis_=="attribute" &&
				steps_.top(1).name_=="*" &&
				steps_.top(2).name_==".any")
			{
				r+= ".any\\";
				r+= steps_.top(0).name_;
			}
			else if(
				steps_.size()>=3 &&
				steps_.top(1).name_!="*" &&
				steps_.top(2).name_==".any")
			{
				r+= ".any\\";
				r+= steps_.top(1).name_;
				r+= '\\';
				r+= steps_.top(0).name_;
			}
			else if (steps_.size()>=2)
			{
				r+= steps_.top(1).name_;
				r+= '\\';
				r+= steps_.top(0).name_;
			}
			return r;
		}
		const std::string step_axis() const
		{
			std::string r;
			if(!steps_.empty())
				r= steps_.top().axis_;
			return r;
		}
		const std::string step_name() const
		{
			std::string r;
			if(!steps_.empty())
				r= steps_.top().name_;
			return r;
		}
		size_t size() const
		{
			return steps_.size();
		}
	private:
		StepStack steps_;
	};

#line 147 "XPathParser.hpp"
class XPathParser : public ANTLR_USE_NAMESPACE(antlr)LLkParser, public XPathParserTokenTypes
{
#line 1 "XPathParser.g"
#line 151 "XPathParser.hpp"
public:
	void initializeASTFactory( ANTLR_USE_NAMESPACE(antlr)ASTFactory& factory );
protected:
	XPathParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf, int k);
public:
	XPathParser(ANTLR_USE_NAMESPACE(antlr)TokenBuffer& tokenBuf);
protected:
	XPathParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer, int k);
public:
	XPathParser(ANTLR_USE_NAMESPACE(antlr)TokenStream& lexer);
	XPathParser(const ANTLR_USE_NAMESPACE(antlr)ParserSharedInputState& state);
	int getNumTokens() const
	{
		return XPathParser::NUM_TOKENS;
	}
	const char* getTokenName( int type ) const
	{
		if( type > getNumTokens() ) return 0;
		return XPathParser::tokenNames[type];
	}
	const char* const* getTokenNames() const
	{
		return XPathParser::tokenNames;
	}
	public: void xpath(
		QueryContext &context
	);
	public: void expr(
		QueryContext &context,ParserContext &pc
	);
	public: void locationPath(
		QueryContext &context,ParserContext &pc
	);
	public: void relativeLocationPath(
		QueryContext &context,ParserContext &pc
	);
	public: void absoluteLocationPath(
		QueryContext &context,ParserContext &pc
	);
	public: void axisName();
	public: void step(
		QueryContext &context,ParserContext &pc
	);
	public: void steps(
		QueryContext &context,ParserContext &pc
	);
	public: void axisSpecifier();
	public: void nodeTest(
		QueryContext &context,ParserContext &pc
	);
	public: void predicates(
		QueryContext &context,ParserContext &pc
	);
	public: void abbreviatedStep(
		QueryContext &context,ParserContext &pc
	);
	public: void predicate(
		QueryContext &context,ParserContext &pc
	);
	public: void nameTest(
		QueryContext &context,ParserContext &pc
	);
	public: void orExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void primaryExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void variableReference(
		QueryContext &context,ParserContext &pc
	);
	public: void literal();
	public: void number();
	public: void functionCall(
		QueryContext &context,ParserContext &pc
	);
	public: void functionName(
		QueryContext &context,ParserContext &pc
	);
	public: void argument(
		QueryContext &context,ParserContext &pc
	);
	public: void unionExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void pathExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void filterExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void andExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void equalityExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void relationalExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void additiveExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void multiplicativeExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void unaryExpr(
		QueryContext &context,ParserContext &pc
	);
	public: void qName(
		QueryContext &context,ParserContext &pc
	);
private:
	static const char* tokenNames[];
#ifndef NO_STATIC_CONSTS
	static const int NUM_TOKENS = 67;
#else
	enum {
		NUM_TOKENS = 67
	};
#endif
	
	static const unsigned long _tokenSet_0_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_0;
	static const unsigned long _tokenSet_1_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_1;
	static const unsigned long _tokenSet_2_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_2;
	static const unsigned long _tokenSet_3_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_3;
	static const unsigned long _tokenSet_4_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_4;
	static const unsigned long _tokenSet_5_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_5;
	static const unsigned long _tokenSet_6_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_6;
	static const unsigned long _tokenSet_7_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_7;
	static const unsigned long _tokenSet_8_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_8;
	static const unsigned long _tokenSet_9_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_9;
	static const unsigned long _tokenSet_10_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_10;
	static const unsigned long _tokenSet_11_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_11;
	static const unsigned long _tokenSet_12_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_12;
	static const unsigned long _tokenSet_13_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_13;
	static const unsigned long _tokenSet_14_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_14;
	static const unsigned long _tokenSet_15_data_[];
	static const ANTLR_USE_NAMESPACE(antlr)BitSet _tokenSet_15;
};

#endif /*INC_XPathParser_hpp_*/
