#ifndef _QueryParser_h_ #define _QueryParser_h_ #include "htString.h" #include "Query.h" // // query lexer // abstract class // // defines terminal symbols 'end' and 'quote' // Set() sets the query string and advances to first token // Next() advances to next token // class QueryLexer { public: virtual ~QueryLexer(); void Set(const String &query_string); void Next(); virtual bool IsWord() const = 0; bool IsQuote() const; bool IsEnd() const; const String &Value() const { return current; } const String &FullString() const { return query; } protected: QueryLexer(); String query; String current; }; // // query parser // abstract class // // The main public interface consists on Parse() // which returns a query tree after parsing a query string. // The subclasses must provide a lexer // class QueryParser { public: virtual ~QueryParser() {} Query *Parse(const String &query_string); const String &Error() const { return error; } protected: QueryParser() {} virtual Query *ParseExpression() = 0; virtual QueryLexer &Token() = 0; Query *ParseWord(); Query *ParseExactWord(); Query *ParsePhrase(); void Expected(const String &what); private: String error; }; // // query lexer for simple (all/any) queries // class SimpleLexer : public QueryLexer { public: SimpleLexer() : QueryLexer() {} bool IsWord() const { return !IsEnd(); } }; // // query parser for simple (all/any word) queries // abstract class // class SimpleQueryParser : public QueryParser { public: virtual ~SimpleQueryParser() {} Query *Parse(const String &query_string); protected: SimpleQueryParser() {} virtual OperatorQuery *MakeQuery() = 0; private: Query *ParseExpression(); Query *ParseTerm(); QueryLexer &Token() { return token; } SimpleLexer token; }; // // query parser for 'and' (all words) simple queries // class AndQueryParser : public SimpleQueryParser { public: AndQueryParser(); private: OperatorQuery *MakeQuery() { return new AndQuery; } }; // // query parser for 'or' (any word) simple queries // class OrQueryParser : public SimpleQueryParser { public: OrQueryParser(); private: OperatorQuery *MakeQuery() { return new OrQuery; } }; // // query lexer for boolean expressions // defines terminal symbols "word", and, or, not, near, (, ), / // class BooleanLexer : public QueryLexer { public: bool IsWord() const; bool IsAnd() const; bool IsOr() const; bool IsNear() const; bool IsNot() const; bool IsLeftParen() const; bool IsRightParen() const; bool IsSlash() const; }; class BooleanQueryParser : public QueryParser { public: BooleanQueryParser() {} ~BooleanQueryParser() {} private: Query *ParseExpression(); Query *ParseAnd(); Query *ParseNot(); Query *ParseNear(); Query *ParseFactor(); QueryLexer &Token() { return token; } BooleanLexer token; }; class GParser : public QueryParser { public: GParser() {} ~GParser() {} private: Query *ParseExpression(); Query *ParseFactor(); OperatorQuery *MakeOperatorQuery(const String &op) const; QueryLexer &Token() { return token; } BooleanLexer token; }; #endif