// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef LOG_QUERY_H #define LOG_QUERY_H #include "nel/misc/types_nl.h" #include #include "nel/misc/common.h" #include "server_share/logger_service_itf.h" #include "game_share/shard_names.h" #include "logger_service.h" #include "log_storage.h" struct EIncompatibleType : public NLMISC::Exception { LGS::TSupportedParamType ValueType; LGS::TSupportedParamType RequiredType; EIncompatibleType(LGS::TSupportedParamType valueType, LGS::TSupportedParamType requiredType) : ValueType(valueType), RequiredType(requiredType) { } virtual const char *what() const throw() { return "Incompatible types"; } }; /// A set of log entry index, used as 'result set' for a predicate node typedef std::set TLogEntries; /// Define a time slice for opening log file struct TTimeSlice { /// the inclusive start date uint32 StartDate; /// The excluded end date uint32 EndDate; }; const TTimeSlice FullTimeSlice = {0, ~0}; /// Defile the complete selected time line typedef std::vector TTimeLine; /// The token returned by the lexer function (or manually set by parser) enum TTokenType { tt_ID, tt_TYPE, tt_STRING, tt_INT, tt_NAKED_HEXA, tt_LONG, tt_FLOAT, tt_DATE, tt_ENTITY_ID, tt_ITEM_ID, tt_OPEN_PAR, tt_CLOSE_PAR, tt_OPEN_BRACKET, tt_CLOSE_BRACKET, tt_OPEN_BRACE, tt_CLOSE_BRACE, tt_COLON, tt_DASH, tt_DOT, tt_LESS, tt_LESS_EQUAL, tt_GREATER, tt_GREATER_EQUAL, tt_EQUAL, tt_like, tt_full_context, tt_output_prefix, tt_NOT_EQUAL, tt_or, tt_and, tt_yesterday, tt_secs, tt_mins, tt_hours, tt_days, tt_weeks, tt_months, tt_years, tt_EOF }; /// Base class for the parsed request tree struct TQueryNode { TQueryNode *LeftNode; TQueryNode *RightNode; // TQueryNode *ParentNode; TQueryNode() : LeftNode(NULL), RightNode(NULL) // ParentNode(NULL) {} virtual ~TQueryNode() { if (LeftNode) delete LeftNode; if (RightNode) delete RightNode; } // init the node virtual bool init() =0; /// Evaluate the node result virtual TLogEntries evalNode(const CLogStorage &logs) =0; /// Evaluate a date against the predicate (only test the date predicate) virtual TTimeLine evalDate() =0; /// dump the node void dump(NLMISC::CLog &log, const std::string &tab) const { dumpNode(log, tab); if (LeftNode) { log.displayNL("%s + => ", tab.c_str()); LeftNode->dump(log, tab+"\t"); } if (RightNode) { log.displayNL("%s + => ", tab.c_str()); RightNode->dump(log, tab+"\t"); } } /// Display node content virtual void dumpNode(NLMISC::CLog &log, const std::string &tab) const =0; }; //extern LGS::TSupportedParamType ConversionTable[LGS::TSupportedParamType::nb_enum_items][LGS::TSupportedParamType::nb_enum_items]; extern bool ConversionTable[LGS::TSupportedParamType::nb_enum_items][LGS::TSupportedParamType::nb_enum_items]; /// A type to store the list of selected parameter and log types struct TSelectedParam { uint32 LogDefIndex; bool ListParam; uint32 ParamIndex; }; /// For each param id, associate a vector of log def index typedef std::map > TSelectedParams; /// A big function to do all allowed type conversion inline LGS::TParamValue convertParam(const LGS::TParamValue &value, LGS::TSupportedParamType type) { switch (value.getType().getValue()) { case LGS::TSupportedParamType::spt_uint32: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: return value; case LGS::TSupportedParamType::spt_uint64: return LGS::TParamValue((uint64)value.get_uint32()); case LGS::TSupportedParamType::spt_sint32: return LGS::TParamValue((sint32)value.get_uint32()); case LGS::TSupportedParamType::spt_float: return LGS::TParamValue((float)value.get_uint32()); case LGS::TSupportedParamType::spt_string: return LGS::TParamValue(NLMISC::toString(value.get_uint32())); case LGS::TSupportedParamType::spt_entityId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sheetId: return LGS::TParamValue(NLMISC::CSheetId(value.get_uint32())); case LGS::TSupportedParamType::spt_itemId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); } break; case LGS::TSupportedParamType::spt_uint64: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: return LGS::TParamValue((uint32)value.get_uint64()); case LGS::TSupportedParamType::spt_uint64: return value; case LGS::TSupportedParamType::spt_sint32: return LGS::TParamValue((sint32)value.get_uint64()); case LGS::TSupportedParamType::spt_float: return LGS::TParamValue((float)value.get_uint64()); case LGS::TSupportedParamType::spt_string: return LGS::TParamValue(NLMISC::toString(value.get_uint64())); case LGS::TSupportedParamType::spt_entityId: return LGS::TParamValue(NLMISC::CEntityId(value.get_uint64())); case LGS::TSupportedParamType::spt_sheetId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_itemId: return LGS::TParamValue(INVENTORIES::TItemId(value.get_uint64())); } break; case LGS::TSupportedParamType::spt_sint32: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: return LGS::TParamValue((uint32)value.get_sint32()); case LGS::TSupportedParamType::spt_uint64: return LGS::TParamValue((uint64)value.get_sint32()); case LGS::TSupportedParamType::spt_sint32: return value; case LGS::TSupportedParamType::spt_float: return LGS::TParamValue((float)value.get_sint32()); case LGS::TSupportedParamType::spt_string: return LGS::TParamValue(NLMISC::toString(value.get_sint32())); case LGS::TSupportedParamType::spt_entityId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sheetId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_itemId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); } break; case LGS::TSupportedParamType::spt_float: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: return LGS::TParamValue((uint64)value.get_float()); case LGS::TSupportedParamType::spt_uint64: return LGS::TParamValue((uint64)value.get_float()); case LGS::TSupportedParamType::spt_sint32: return LGS::TParamValue((sint32)value.get_float()); case LGS::TSupportedParamType::spt_float: return value; case LGS::TSupportedParamType::spt_string: return LGS::TParamValue(NLMISC::toString(value.get_float())); case LGS::TSupportedParamType::spt_entityId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sheetId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_itemId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); } break; case LGS::TSupportedParamType::spt_string: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: { uint32 tmp; NLMISC::fromString(value.get_string(), tmp); return LGS::TParamValue(tmp); } case LGS::TSupportedParamType::spt_uint64: return LGS::TParamValue((uint64)atol(value.get_string().c_str())); case LGS::TSupportedParamType::spt_sint32: { sint32 tmp; NLMISC::fromString(value.get_string(), tmp); return LGS::TParamValue(tmp); } case LGS::TSupportedParamType::spt_float: return LGS::TParamValue((float)atof(value.get_string().c_str())); case LGS::TSupportedParamType::spt_string: return value; case LGS::TSupportedParamType::spt_entityId: return LGS::TParamValue(NLMISC::CEntityId(value.get_string())); case LGS::TSupportedParamType::spt_sheetId: return LGS::TParamValue(NLMISC::CSheetId(value.get_string())); case LGS::TSupportedParamType::spt_itemId: return LGS::TParamValue(INVENTORIES::TItemId(value.get_string())); } break; case LGS::TSupportedParamType::spt_entityId: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_uint64: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sint32: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_float: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_string: return value.get_entityId().toString(); case LGS::TSupportedParamType::spt_entityId: return value; case LGS::TSupportedParamType::spt_sheetId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_itemId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); } break; case LGS::TSupportedParamType::spt_sheetId: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_uint64: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sint32: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_float: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_string: return value.get_sheetId().toString(true); case LGS::TSupportedParamType::spt_entityId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sheetId: return value; case LGS::TSupportedParamType::spt_itemId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); } break; case LGS::TSupportedParamType::spt_itemId: switch (type.getValue()) { case LGS::TSupportedParamType::spt_uint32: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_uint64: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sint32: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_float: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_string: return value.get_itemId().toString(); case LGS::TSupportedParamType::spt_entityId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_sheetId: throw EIncompatibleType(value.getType().getValue(), type.getValue()); case LGS::TSupportedParamType::spt_itemId: return value; } break; } nlstop; return LGS::TParamValue(); } /// The combiner node, may be specialized with 'or' or 'and' combiner. template struct TCombineNode : public TQueryNode { virtual bool init() { return true; } /// Evaluate the node result virtual TLogEntries evalNode(const CLogStorage &logs) { TLogEntries leftEntries, rightEntries; nlassert(LeftNode && RightNode); leftEntries = LeftNode->evalNode(logs); rightEntries = RightNode->evalNode(logs); // combine the two entries Combiner comb; return comb(leftEntries, rightEntries); } /// Evaluate a date against the predicate (only test the date predicate) virtual TTimeLine evalDate() { nlassert(LeftNode && RightNode); TTimeLine left = LeftNode->evalDate(); TTimeLine right = RightNode->evalDate(); Combiner comb; return comb(left, right); } virtual void dumpNode(NLMISC::CLog &log, const std::string &tab) const { log.displayNL("%s%s", tab.c_str(), typeid(this).name()); } }; /// Given the parameter index selected, build the list of logs that use the selected param inline void buildSelectedLogList(const std::vector &selectedIndex, const CLogStorage &logs, const std::vector &selectedParams, TLogEntries &result) { // for each log type to test for (uint j=0; j struct TTypePredicateNode : public TQueryNode { /// The reference value used to compute the predicate LGS::TParamValue _RefValue; /// The type of parameter that we check LGS::TSupportedParamType _ParamType; /// The log info vector const TLogDefinitions &_LogDefs; /// The list of parameter that match the name/type TSelectedParams _SelectedParams; TTypePredicateNode(const LGS::TParamValue &refValue, const LGS::TSupportedParamType ¶mType, const TLogDefinitions &logDefs ) : _RefValue(refValue), _ParamType(paramType), _LogDefs(logDefs) { } bool init() { // Build a list of compatible parameters for (uint i=0; i<_LogDefs.size(); ++i) { const LGS::TLogDefinition &logDef = _LogDefs[i]; // read each param for (uint j=0; j selectedIndex; const CLogStorage::TLogParamId &lpi = first->first; const std::vector &sps = first->second; // retrieve the table for this param CLogStorage::TParamsTables::const_iterator it(logs._ParamTables.find(lpi)); if (it != logs._ParamTables.end()) { const CLogStorage::TParamsTable &pt = it->second; // parse each entry of the param table for (uint j=0; jsecond.size(); ++i) { const LGS::TLogDefinition &logDef = _LogDefs[first->second[i].LogDefIndex]; log.displayNL("%s Matching in log '%s', parameter %u", tab.c_str(), logDef.getLogName().c_str(), first->second[i].ParamIndex); } } } }; /// The predicate node. This node apply the operator with the reference value and the matching log paramters name template struct TPredicateNode : public TQueryNode { /// The reference value used to compute the predicate LGS::TParamValue _RefValue; /// Name of the parameter std::string _ParameterName; /// The log info vector const TLogDefinitions &_LogDefs; /// The list of parameter that match the name/type TSelectedParams _SelectedParams; TPredicateNode(const LGS::TParamValue &refValue, const std::string ¶mName, const TLogDefinitions &logDefs ) : _RefValue(refValue), _ParameterName(paramName), _LogDefs(logDefs) { } bool init() { if (_ParameterName == "LogDate") { if (!ConversionTable[_RefValue.getType().getValue()][LGS::TSupportedParamType::spt_uint32]) throw EIncompatibleType(_RefValue.getType().getValue(), LGS::TSupportedParamType::spt_uint32); // any log is applicable CLogStorage::TLogParamId lpi; lpi.ParamName = "LogDate"; lpi.ParamType = LGS::TSupportedParamType::invalid_val; // _SelectedParams.insert(std::make_pair(logDef.getLogName(), logDef.getParams().size())); // Create a fake entry in the selected param container _SelectedParams[lpi]; } else if (_ParameterName == "LogName") { if (!ConversionTable[_RefValue.getType().getValue()][LGS::TSupportedParamType::spt_string]) throw EIncompatibleType(_RefValue.getType().getValue(), LGS::TSupportedParamType::spt_string); // any log is applicable CLogStorage::TLogParamId lpi; lpi.ParamName = "LogName"; lpi.ParamType = LGS::TSupportedParamType::invalid_val; // Create a fake entry in the selected param container _SelectedParams[lpi]; } else if (_ParameterName == "ShardId") { if (!ConversionTable[_RefValue.getType().getValue()][LGS::TSupportedParamType::spt_uint32] &&!ConversionTable[_RefValue.getType().getValue()][LGS::TSupportedParamType::spt_string]) throw EIncompatibleType(_RefValue.getType().getValue(), LGS::TSupportedParamType::spt_uint32); // any log is applicable CLogStorage::TLogParamId lpi; lpi.ParamName = "ShardId"; lpi.ParamType = LGS::TSupportedParamType::invalid_val; // Create a fake entry in the selected param container _SelectedParams[lpi]; } else { // Build a list of compatible parameters for (uint i=0; i<_LogDefs.size(); ++i) { const LGS::TLogDefinition &logDef = _LogDefs[i]; { // read each param for (uint j=0; jfirst.ParamType == LGS::TSupportedParamType::invalid_val) { if(_ParameterName == "LogDate") { TTimeSlice ts; TTimeLine tl; switch (Operator::getOperatorType()) { case tt_LESS: ts.StartDate = 0; ts.EndDate = _RefValue.get_uint32(); tl.push_back(ts); break; case tt_LESS_EQUAL: ts.StartDate = 0; ts.EndDate = _RefValue.get_uint32()+1; tl.push_back(ts); break; case tt_GREATER: ts.StartDate = _RefValue.get_uint32()+1; ts.EndDate = ~0; tl.push_back(ts); break; case tt_GREATER_EQUAL: ts.StartDate = _RefValue.get_uint32(); ts.EndDate = ~0; tl.push_back(ts); break; case tt_EQUAL: ts.StartDate = _RefValue.get_uint32(); ts.EndDate = _RefValue.get_uint32()+1; tl.push_back(ts); break; case tt_NOT_EQUAL: // need to push 2 slice ts.StartDate = 0; ts.EndDate = _RefValue.get_uint32(); tl.push_back(ts); ts.StartDate = _RefValue.get_uint32()+1; ts.EndDate = ~0; tl.push_back(ts); break; default: break; } return tl; } } // otherwise, return full time range return TTimeLine(1, FullTimeSlice); } TLogEntries evalNode(const CLogStorage &logs) { // apply the operator on all the log entry Operator op; TLogEntries ret; if (_SelectedParams.size() == 1 && _SelectedParams.begin()->first.ParamType == LGS::TSupportedParamType::invalid_val) { if(_ParameterName == "LogDate") { LGS::TParamValue ref = convertParam(_RefValue, LGS::TSupportedParamType::spt_uint32); // this is a date comparison for (uint i=0; i matchingLogs; LGS::TParamValue ref = convertParam(_RefValue, LGS::TSupportedParamType::spt_string); // select only log of a given log name (aka type) for (uint32 defIndex=0; defIndex<_LogDefs.size(); ++defIndex) { if (op(LGS::TParamValue(_LogDefs[defIndex].getLogName()), ref)) matchingLogs.push_back(defIndex); } for (uint32 j=0; j matchingLogs; LGS::TParamValue ref; // if we have a string, we interpret it as a shard name if (_RefValue.getType() == LGS::TSupportedParamType::spt_string) ref = LGS::TParamValue(CShardNames::getInstance().getShardId(_RefValue.get_string())); else ref = convertParam(_RefValue, LGS::TSupportedParamType::spt_uint32); // select only log of the correct shard id for (uint i=0; i selectedIndex; const CLogStorage::TLogParamId &lpi = first->first; const std::vector &sps = first->second; // retrieve the table for this param CLogStorage::TParamsTables::const_iterator it(logs._ParamTables.find(lpi)); if (it != logs._ParamTables.end()) { const CLogStorage::TParamsTable &pt = it->second; LGS::TParamValue ref; if (Operator::getOperatorType() == tt_like) { // special case, keep the reference type ref = _RefValue; } else { ref = convertParam(_RefValue, lpi.ParamType); } // parse each entry of the param table for (uint j=0; jsecond.size(); ++i) { const LGS::TLogDefinition &logDef = _LogDefs[first->second[i].LogDefIndex]; log.displayNL("%s Matching in log '%s', parameter %u", tab.c_str(), logDef.getLogName().c_str(), first->second[i].ParamIndex); } } } }; /// The operators classes /// NB : all operator are implemented by using the '==' and '<' operator struct TEqualOp { template bool operator () (const T &value, const T &ref) const { return value == ref; } static TTokenType getOperatorType() { return tt_EQUAL;}; }; struct TLessOp { template bool operator () (const T &value, const T &ref) const { return value < ref; } static TTokenType getOperatorType() { return tt_LESS;}; }; struct TLessEqualOp { template bool operator () (const T &value, const T &ref) const { return value == ref || value < ref; } static TTokenType getOperatorType() { return tt_LESS_EQUAL;}; }; struct TGreaterOp { template bool operator () (const T &value, const T &ref) const { return !(value < ref || value == ref); } static TTokenType getOperatorType() { return tt_GREATER;}; }; struct TGreaterEqualOp { template bool operator () (const T &value, const T &ref) const { return !(value < ref) ; } static TTokenType getOperatorType() { return tt_GREATER_EQUAL;}; }; struct TNotEqualOp { template bool operator () (const T &value, const T &ref) const { return !(value == ref); } static TTokenType getOperatorType() { return tt_NOT_EQUAL;}; }; struct TLikeOp { template bool operator () (const T &value, const T &ref) const { std::string refStr = NLMISC::toString(ref); std::string valueStr = NLMISC::toString(value); return valueStr.find(refStr) != std::string::npos; } static TTokenType getOperatorType() { return tt_like;}; }; struct TOrCombiner { TLogEntries operator () (const TLogEntries &leftEntry, const TLogEntries &rightEntry) const { TLogEntries ret; std::set_union(leftEntry.begin(), leftEntry.end(), rightEntry.begin(), rightEntry.end(), std::inserter(ret, ret.begin())); return ret; } TTimeLine operator ()(const TTimeLine &left, const TTimeLine &right) const { TTimeLine ret; std::map timeTags; // first loop to init all entry needed to zero for (uint i=0; i::iterator first(timeTags.begin()), last(timeTags.end()); for (; first != last; ++first) { if (count == 0 && first->second > 0) ts.StartDate = first->first; else if (count > 0 && count+first->second == 0) { ts.EndDate = first->first; ret.push_back(ts); } count += first->second; } return ret; } }; struct TAndCombiner { TLogEntries operator () (const TLogEntries &leftEntry, const TLogEntries &rightEntry) const { TLogEntries ret; std::set_intersection(leftEntry.begin(), leftEntry.end(), rightEntry.begin(), rightEntry.end(), std::inserter(ret, ret.begin())); return ret; } TTimeLine operator ()(const TTimeLine &left, const TTimeLine &right) const { TTimeLine ret; std::map timeTags; // first loop to init all entry needed to zero for (uint i=0; i::iterator first(timeTags.begin()), last(timeTags.end()); for (; first != last; ++first) { if (count < 2 && count+first->second == 2) ts.StartDate = first->first; else if (count == 2 && first->second < 0) { ts.EndDate = first->first; ret.push_back(ts); } count += first->second; } return ret; } }; /** This class implement the query parser. * It take a query string in input and return the root of a tree that implement * the request. */ class CQueryParser { /// Iterator in the parser are string iterator typedef std::string::const_iterator iterator; /// Struct to store a token returned by the lexer struct TToken { /// The position that generated this token iterator It; /// The token type TTokenType TokenType; /// The text value of the token std::string Text; }; typedef std::map TKeywords; /// A set a predefined keyword. If a token found by the parser is equal to one /// of the keyword, then the lexer substitute the token type with the /// one associated with the keyword TKeywords _Keywords; /// The log definition used to build the query tree (needed to build the list /// of matching log types in the predicate nodes) const TLogDefinitions &_LogDefs; public: /// Exception class thrown by the lexer/parser in case or error struct EInvalidQuery : public NLMISC::Exception { /// The iterator in the string where the error is detected iterator It; /// The error string const char *ErrorStr; EInvalidQuery(iterator it, const char *erroStr) : It(it), ErrorStr(erroStr) {} virtual const char* what() const throw () { return ErrorStr; } }; struct TParserResult { /// The query tree mutable std::auto_ptr QueryTree; /// Option to extract full context with selected logs bool FullContext; /// Option to add a prefix to the output file std::string OutputPrefix; TParserResult() : FullContext(false) { } TParserResult(const TParserResult &other) : QueryTree(other.QueryTree), FullContext(other.FullContext), OutputPrefix(other.OutputPrefix) { } }; /// Constructor CQueryParser(const TLogDefinitions &logDefs); /// Parse the queryStr and return the root of the query tree TParserResult parseQuery(const std::string &queryStr, bool parseOnlyOption); private: /// Convert a string into a supported param type (if possible) LGS::TSupportedParamType parseParamType(const std::string &typeName); /// Parse the options at the start of the query void parseOptions(CQueryParser::TParserResult &parserResult, CQueryParser::iterator &it, CQueryParser::iterator end); /// Parse one option bool parseOption(CQueryParser::TParserResult &parserResult, CQueryParser::iterator &it, CQueryParser::iterator end); /// Build a predicate node according to the specified operator, reference value and left value type. TQueryNode *buildPredicate(const LGS::TParamValue &refVal, const TToken &operatorType, const TToken &leftValue, iterator &it, iterator end); /// Parse a singed integer sint32 parseSint(iterator &it, iterator end); /// Parse an item id std::string parseItemId(iterator &it, iterator end); /// Parse an entity id std::string parseEntityId(iterator &it, iterator end); /// Parse a constant value LGS::TParamValue parseConstant(iterator &it, iterator end); /// Parse a predicate TQueryNode *parsePredicate(iterator &it, iterator end); /// Parse an atom (either a parenthesis grouping or an atom) TQueryNode *parseAtom(iterator &it, iterator end); /// Parse an 'and' expression TQueryNode *parseAndExpr(iterator &it, iterator end); /// Parse an expression TQueryNode *parseExpr(iterator &it, iterator end); /// Parse a date bool parseDATE(iterator &it, iterator end); /// parse an ID bool parseID(iterator &it, iterator end); /// parse an STRING bool parseSTRING(iterator &it, iterator end); /// parse an FLOAT bool parseFLOAT(iterator &it, iterator end); /// Parse a long int (64 bits) bool parseLONG_INT(iterator &it, iterator end); /// Parse a naked hexa (ie. without the '0x' prefix) bool parseNAKED_HEXA(iterator &it, iterator end); /// parse an INT bool parseINT(iterator &it, iterator end); /// The lexer TToken getNextToken(iterator &it, iterator end); /// Skip the WhiteSpace iterator skipWS(iterator it, iterator end); /// Check is a string contains a naked hexadecimal value bool isNakedHexa(const std::string &text); }; #endif //LOG_QUERY_H