diff options
Diffstat (limited to 'src/mongo/db/cst/bson_lexer.cpp')
-rw-r--r-- | src/mongo/db/cst/bson_lexer.cpp | 330 |
1 files changed, 149 insertions, 181 deletions
diff --git a/src/mongo/db/cst/bson_lexer.cpp b/src/mongo/db/cst/bson_lexer.cpp index 5fccfac805f..dbce1618749 100644 --- a/src/mongo/db/cst/bson_lexer.cpp +++ b/src/mongo/db/cst/bson_lexer.cpp @@ -31,7 +31,7 @@ #include "mongo/base/string_data.h" #include "mongo/db/cst/bson_lexer.h" -#include "mongo/db/cst/pipeline_parser_gen.hpp" +#include "mongo/db/cst/parser_gen.hpp" #include "mongo/util/string_map.h" namespace mongo { @@ -42,105 +42,109 @@ namespace { // Mapping of reserved keywords to BSON token. Any key which is not included in this map is assumed // to be a user field name and is treated as a terminal by the parser. -const StringMap<PipelineParserGen::token_type> reservedKeyLookup = { - {"_id", PipelineParserGen::token::ID}, +const StringMap<ParserGen::token_type> reservedKeyLookup = { + {"_id", ParserGen::token::ID}, // Stages and their arguments. - {"$_internalInhibitOptimization", PipelineParserGen::token::STAGE_INHIBIT_OPTIMIZATION}, - {"$limit", PipelineParserGen::token::STAGE_LIMIT}, - {"$project", PipelineParserGen::token::STAGE_PROJECT}, - {"$sample", PipelineParserGen::token::STAGE_SAMPLE}, - {"size", PipelineParserGen::token::ARG_SIZE}, - {"$skip", PipelineParserGen::token::STAGE_SKIP}, - {"$unionWith", PipelineParserGen::token::STAGE_UNION_WITH}, - {"coll", PipelineParserGen::token::ARG_COLL}, - {"pipeline", PipelineParserGen::token::ARG_PIPELINE}, + {"$_internalInhibitOptimization", ParserGen::token::STAGE_INHIBIT_OPTIMIZATION}, + {"$limit", ParserGen::token::STAGE_LIMIT}, + {"$project", ParserGen::token::STAGE_PROJECT}, + {"$sample", ParserGen::token::STAGE_SAMPLE}, + {"size", ParserGen::token::ARG_SIZE}, + {"$skip", ParserGen::token::STAGE_SKIP}, + {"$unionWith", ParserGen::token::STAGE_UNION_WITH}, + {"coll", ParserGen::token::ARG_COLL}, + {"pipeline", ParserGen::token::ARG_PIPELINE}, // Expressions - {"$add", PipelineParserGen::token::ADD}, - {"$atan2", PipelineParserGen::token::ATAN2}, - {"$and", PipelineParserGen::token::AND}, - {"$or", PipelineParserGen::token::OR}, - {"$not", PipelineParserGen::token::NOT}, - {"$const", PipelineParserGen::token::CONST_EXPR}, - {"$literal", PipelineParserGen::token::LITERAL}, - {"$cmp", PipelineParserGen::token::CMP}, - {"$eq", PipelineParserGen::token::EQ}, - {"$gt", PipelineParserGen::token::GT}, - {"$gte", PipelineParserGen::token::GTE}, - {"$lt", PipelineParserGen::token::LT}, - {"$lte", PipelineParserGen::token::LTE}, - {"$ne", PipelineParserGen::token::NE}, - {"$convert", PipelineParserGen::token::CONVERT}, - {"input", PipelineParserGen::token::ARG_INPUT}, - {"to", PipelineParserGen::token::ARG_TO}, - {"onError", PipelineParserGen::token::ARG_ON_ERROR}, - {"onNull", PipelineParserGen::token::ARG_ON_NULL}, - {"$toBool", PipelineParserGen::token::TO_BOOL}, - {"$toDate", PipelineParserGen::token::TO_DATE}, - {"$toDecimal", PipelineParserGen::token::TO_DECIMAL}, - {"$toDouble", PipelineParserGen::token::TO_DOUBLE}, - {"$toInt", PipelineParserGen::token::TO_INT}, - {"$toLong", PipelineParserGen::token::TO_LONG}, - {"$toObjectId", PipelineParserGen::token::TO_OBJECT_ID}, - {"$toString", PipelineParserGen::token::TO_STRING}, - {"$type", PipelineParserGen::token::TYPE}, - {"$abs", PipelineParserGen::token::ABS}, - {"$ceil", PipelineParserGen::token::CEIL}, - {"$divide", PipelineParserGen::token::DIVIDE}, - {"$exp", PipelineParserGen::token::EXPONENT}, - {"$floor", PipelineParserGen::token::FLOOR}, - {"$ln", PipelineParserGen::token::LN}, - {"$log", PipelineParserGen::token::LOG}, - {"$log10", PipelineParserGen::token::LOGTEN}, - {"$mod", PipelineParserGen::token::MOD}, - {"$multiply", PipelineParserGen::token::MULTIPLY}, - {"$pow", PipelineParserGen::token::POW}, - {"$round", PipelineParserGen::token::ROUND}, - {"$sqrt", PipelineParserGen::token::SQRT}, - {"$subtract", PipelineParserGen::token::SUBTRACT}, - {"$trunc", PipelineParserGen::token::TRUNC}, - {"$concat", PipelineParserGen::token::CONCAT}, - {"$dateFromString", PipelineParserGen::token::DATE_FROM_STRING}, - {"$dateToString", PipelineParserGen::token::DATE_TO_STRING}, - {"$indexOfBytes", PipelineParserGen::token::INDEX_OF_BYTES}, - {"$indexOfCP", PipelineParserGen::token::INDEX_OF_CP}, - {"$ltrim", PipelineParserGen::token::LTRIM}, - {"$meta", PipelineParserGen::token::META}, - {"$regexFind", PipelineParserGen::token::REGEX_FIND}, - {"$regexFindAll", PipelineParserGen::token::REGEX_FIND_ALL}, - {"$regexMatch", PipelineParserGen::token::REGEX_MATCH}, - {"$replaceOne", PipelineParserGen::token::REPLACE_ONE}, - {"$replaceAll", PipelineParserGen::token::REPLACE_ALL}, - {"$rtrim", PipelineParserGen::token::RTRIM}, - {"$split", PipelineParserGen::token::SPLIT}, - {"$strLenBytes", PipelineParserGen::token::STR_LEN_BYTES}, - {"$strLenCP", PipelineParserGen::token::STR_LEN_CP}, - {"$strcasecmp", PipelineParserGen::token::STR_CASE_CMP}, - {"$substr", PipelineParserGen::token::SUBSTR}, - {"$substrBytes", PipelineParserGen::token::SUBSTR_BYTES}, - {"$substrCP", PipelineParserGen::token::SUBSTR_CP}, - {"$toLower", PipelineParserGen::token::TO_LOWER}, - {"$trim", PipelineParserGen::token::TRIM}, - {"$toUpper", PipelineParserGen::token::TO_UPPER}, - {"dateString", PipelineParserGen::token::ARG_DATE_STRING}, - {"format", PipelineParserGen::token::ARG_FORMAT}, - {"timezone", PipelineParserGen::token::ARG_TIMEZONE}, - {"date", PipelineParserGen::token::ARG_DATE}, - {"chars", PipelineParserGen::token::ARG_CHARS}, - {"regex", PipelineParserGen::token::ARG_REGEX}, - {"options", PipelineParserGen::token::ARG_OPTIONS}, - {"find", PipelineParserGen::token::ARG_FIND}, - {"replacement", PipelineParserGen::token::ARG_REPLACEMENT}, + {"$add", ParserGen::token::ADD}, + {"$atan2", ParserGen::token::ATAN2}, + {"$and", ParserGen::token::AND}, + {"$or", ParserGen::token::OR}, + {"$not", ParserGen::token::NOT}, + {"$const", ParserGen::token::CONST_EXPR}, + {"$literal", ParserGen::token::LITERAL}, + {"$cmp", ParserGen::token::CMP}, + {"$eq", ParserGen::token::EQ}, + {"$gt", ParserGen::token::GT}, + {"$gte", ParserGen::token::GTE}, + {"$lt", ParserGen::token::LT}, + {"$lte", ParserGen::token::LTE}, + {"$ne", ParserGen::token::NE}, + {"$convert", ParserGen::token::CONVERT}, + {"input", ParserGen::token::ARG_INPUT}, + {"to", ParserGen::token::ARG_TO}, + {"onError", ParserGen::token::ARG_ON_ERROR}, + {"onNull", ParserGen::token::ARG_ON_NULL}, + {"$toBool", ParserGen::token::TO_BOOL}, + {"$toDate", ParserGen::token::TO_DATE}, + {"$toDecimal", ParserGen::token::TO_DECIMAL}, + {"$toDouble", ParserGen::token::TO_DOUBLE}, + {"$toInt", ParserGen::token::TO_INT}, + {"$toLong", ParserGen::token::TO_LONG}, + {"$toObjectId", ParserGen::token::TO_OBJECT_ID}, + {"$toString", ParserGen::token::TO_STRING}, + {"$type", ParserGen::token::TYPE}, + {"$abs", ParserGen::token::ABS}, + {"$ceil", ParserGen::token::CEIL}, + {"$divide", ParserGen::token::DIVIDE}, + {"$exp", ParserGen::token::EXPONENT}, + {"$floor", ParserGen::token::FLOOR}, + {"$ln", ParserGen::token::LN}, + {"$log", ParserGen::token::LOG}, + {"$log10", ParserGen::token::LOGTEN}, + {"$mod", ParserGen::token::MOD}, + {"$multiply", ParserGen::token::MULTIPLY}, + {"$pow", ParserGen::token::POW}, + {"$round", ParserGen::token::ROUND}, + {"$sqrt", ParserGen::token::SQRT}, + {"$subtract", ParserGen::token::SUBTRACT}, + {"$trunc", ParserGen::token::TRUNC}, + {"$concat", ParserGen::token::CONCAT}, + {"$dateFromString", ParserGen::token::DATE_FROM_STRING}, + {"$dateToString", ParserGen::token::DATE_TO_STRING}, + {"$indexOfBytes", ParserGen::token::INDEX_OF_BYTES}, + {"$indexOfCP", ParserGen::token::INDEX_OF_CP}, + {"$ltrim", ParserGen::token::LTRIM}, + {"$meta", ParserGen::token::META}, + {"$regexFind", ParserGen::token::REGEX_FIND}, + {"$regexFindAll", ParserGen::token::REGEX_FIND_ALL}, + {"$regexMatch", ParserGen::token::REGEX_MATCH}, + {"$replaceOne", ParserGen::token::REPLACE_ONE}, + {"$replaceAll", ParserGen::token::REPLACE_ALL}, + {"$rtrim", ParserGen::token::RTRIM}, + {"$split", ParserGen::token::SPLIT}, + {"$strLenBytes", ParserGen::token::STR_LEN_BYTES}, + {"$strLenCP", ParserGen::token::STR_LEN_CP}, + {"$strcasecmp", ParserGen::token::STR_CASE_CMP}, + {"$substr", ParserGen::token::SUBSTR}, + {"$substrBytes", ParserGen::token::SUBSTR_BYTES}, + {"$substrCP", ParserGen::token::SUBSTR_CP}, + {"$toLower", ParserGen::token::TO_LOWER}, + {"$trim", ParserGen::token::TRIM}, + {"$toUpper", ParserGen::token::TO_UPPER}, + {"dateString", ParserGen::token::ARG_DATE_STRING}, + {"format", ParserGen::token::ARG_FORMAT}, + {"timezone", ParserGen::token::ARG_TIMEZONE}, + {"date", ParserGen::token::ARG_DATE}, + {"chars", ParserGen::token::ARG_CHARS}, + {"regex", ParserGen::token::ARG_REGEX}, + {"options", ParserGen::token::ARG_OPTIONS}, + {"find", ParserGen::token::ARG_FIND}, + {"replacement", ParserGen::token::ARG_REPLACEMENT}, + {"filter", ParserGen::token::ARG_FILTER}, + {"query", ParserGen::token::ARG_QUERY}, + {"q", ParserGen::token::ARG_Q}, + {"sort", ParserGen::token::ARG_SORT}, }; // Mapping of reserved keywords to BSON tokens. Any key which is not included in this map is // assumed to be a user value. -const StringMap<PipelineParserGen::token_type> reservedKeyValueLookup = { - {"randVal", PipelineParserGen::token::RAND_VAL}, - {"textScore", PipelineParserGen::token::TEXT_SCORE}, +const StringMap<ParserGen::token_type> reservedKeyValueLookup = { + {"randVal", ParserGen::token::RAND_VAL}, + {"textScore", ParserGen::token::TEXT_SCORE}, }; -bool isCompound(PipelineParserGen::symbol_type token) { - return token.type_get() == static_cast<int>(PipelineParserGen::token::START_OBJECT) || - token.type_get() == static_cast<int>(PipelineParserGen::token::START_ARRAY); +bool isCompound(ParserGen::symbol_type token) { + return token.type_get() == static_cast<int>(ParserGen::token::START_OBJECT) || + token.type_get() == static_cast<int>(ParserGen::token::START_ARRAY); } } // namespace @@ -148,8 +152,7 @@ bool isCompound(PipelineParserGen::symbol_type token) { void BSONLexer::sortObjTokens() { // A TokenElement is similar to a BSONElement, with the payload being a vector of Bison symbols // if the type is compound (object or array). - using TokenElement = - std::pair<PipelineParserGen::symbol_type, std::vector<PipelineParserGen::symbol_type>>; + using TokenElement = std::pair<ParserGen::symbol_type, std::vector<ParserGen::symbol_type>>; struct TokenElementCompare { bool operator()(const TokenElement& elem1, const TokenElement& elem2) const { return elem1.first.type_get() < elem2.first.type_get(); @@ -157,8 +160,7 @@ void BSONLexer::sortObjTokens() { }; auto currentPosition = _position; - if (_tokens[currentPosition].type_get() != - static_cast<int>(PipelineParserGen::token::START_OBJECT)) { + if (_tokens[currentPosition].type_get() != static_cast<int>(ParserGen::token::START_OBJECT)) { return; } @@ -166,13 +168,12 @@ void BSONLexer::sortObjTokens() { // Increment to get to the first token after the START_OBJECT. We will sort tokens until the // matching END_OBJECT is found. currentPosition++; - while (_tokens[currentPosition].type_get() != - static_cast<int>(PipelineParserGen::token::END_OBJECT)) { + while (_tokens[currentPosition].type_get() != static_cast<int>(ParserGen::token::END_OBJECT)) { invariant(size_t(currentPosition) < _tokens.size()); auto keyToken = _tokens[currentPosition++]; - std::vector<PipelineParserGen::symbol_type> rhsTokens; + std::vector<ParserGen::symbol_type> rhsTokens; rhsTokens.push_back(_tokens[currentPosition]); if (isCompound(_tokens[currentPosition])) { auto braceCount = 1; @@ -183,9 +184,9 @@ void BSONLexer::sortObjTokens() { if (isCompound(_tokens[currentPosition])) braceCount++; if (_tokens[currentPosition].type_get() == - static_cast<int>(PipelineParserGen::token::END_OBJECT) || + static_cast<int>(ParserGen::token::END_OBJECT) || _tokens[currentPosition].type_get() == - static_cast<int>(PipelineParserGen::token::END_ARRAY)) + static_cast<int>(ParserGen::token::END_ARRAY)) braceCount--; rhsTokens.push_back(_tokens[currentPosition++]); @@ -223,43 +224,42 @@ void BSONLexer::tokenize(BSONElement elem, bool includeFieldName) { context.emplace(this, elem.fieldNameStringData()); } else if (elem.fieldNameStringData()[0] == '$') { pushToken(elem.fieldNameStringData(), - PipelineParserGen::token::DOLLAR_PREF_FIELDNAME, + ParserGen::token::DOLLAR_PREF_FIELDNAME, elem.fieldName()); } else { // If we don't care about the keyword, then it's treated as a generic fieldname. - pushToken( - elem.fieldNameStringData(), PipelineParserGen::token::FIELDNAME, elem.fieldName()); + pushToken(elem.fieldNameStringData(), ParserGen::token::FIELDNAME, elem.fieldName()); } } switch (elem.type()) { case BSONType::Array: { - pushToken("start array", PipelineParserGen::token::START_ARRAY); + pushToken("start array", ParserGen::token::START_ARRAY); auto index = 0; - for (auto&& nestedElem : elem.Array()) { + for (auto&& nestedElem : elem.embeddedObject()) { ScopedLocationTracker arrayCtx{this, index++}; // For arrays, do not tokenize the field names. tokenize(nestedElem, false); } - pushToken("end array", PipelineParserGen::token::END_ARRAY); + pushToken("end array", ParserGen::token::END_ARRAY); break; } case BSONType::Object: - pushToken("start object", PipelineParserGen::token::START_OBJECT); + pushToken("start object", ParserGen::token::START_OBJECT); for (auto&& nestedElem : elem.embeddedObject()) { tokenize(nestedElem, true); } - pushToken("end object", PipelineParserGen::token::END_OBJECT); + pushToken("end object", ParserGen::token::END_OBJECT); break; case NumberDouble: if (elem.numberDouble() == 0.0) - pushToken(elem, PipelineParserGen::token::DOUBLE_ZERO); + pushToken(elem, ParserGen::token::DOUBLE_ZERO); else if (elem.numberDouble() == 1.0) - pushToken(elem, PipelineParserGen::token::DOUBLE_ONE); + pushToken(elem, ParserGen::token::DOUBLE_ONE); else if (elem.numberDouble() == -1.0) - pushToken(elem, PipelineParserGen::token::DOUBLE_NEGATIVE_ONE); + pushToken(elem, ParserGen::token::DOUBLE_NEGATIVE_ONE); else - pushToken(elem, PipelineParserGen::token::DOUBLE_OTHER, elem.numberDouble()); + pushToken(elem, ParserGen::token::DOUBLE_OTHER, elem.numberDouble()); break; case BSONType::String: if (auto it = reservedKeyValueLookup.find(elem.valueStringData()); @@ -268,146 +268,114 @@ void BSONLexer::tokenize(BSONElement elem, bool includeFieldName) { } else if (elem.valueStringData()[0] == '$') { if (elem.valueStringData()[1] == '$') { pushToken(elem.valueStringData(), - PipelineParserGen::token::DOLLAR_DOLLAR_STRING, + ParserGen::token::DOLLAR_DOLLAR_STRING, elem.String()); } else { - pushToken(elem.valueStringData(), - PipelineParserGen::token::DOLLAR_STRING, - elem.String()); + pushToken( + elem.valueStringData(), ParserGen::token::DOLLAR_STRING, elem.String()); } } else { - pushToken(elem.valueStringData(), PipelineParserGen::token::STRING, elem.String()); + pushToken(elem.valueStringData(), ParserGen::token::STRING, elem.String()); } break; case BSONType::BinData: { int len; auto data = elem.binData(len); - pushToken( - elem, PipelineParserGen::token::BINARY, BSONBinData{data, len, elem.binDataType()}); + pushToken(elem, ParserGen::token::BINARY, BSONBinData{data, len, elem.binDataType()}); break; } case BSONType::Undefined: - pushToken(elem, PipelineParserGen::token::UNDEFINED, UserUndefined{}); + pushToken(elem, ParserGen::token::UNDEFINED, UserUndefined{}); break; case BSONType::jstOID: - pushToken(elem, PipelineParserGen::token::OBJECT_ID, elem.OID()); + pushToken(elem, ParserGen::token::OBJECT_ID, elem.OID()); break; case Bool: pushToken(elem, - elem.boolean() ? PipelineParserGen::token::BOOL_TRUE - : PipelineParserGen::token::BOOL_FALSE); + elem.boolean() ? ParserGen::token::BOOL_TRUE : ParserGen::token::BOOL_FALSE); break; case BSONType::Date: - pushToken(elem, PipelineParserGen::token::DATE_LITERAL, elem.date()); + pushToken(elem, ParserGen::token::DATE_LITERAL, elem.date()); break; case BSONType::jstNULL: - pushToken(elem, PipelineParserGen::token::JSNULL, UserNull{}); + pushToken(elem, ParserGen::token::JSNULL, UserNull{}); break; case BSONType::RegEx: - pushToken( - elem, PipelineParserGen::token::REGEX, BSONRegEx{elem.regex(), elem.regexFlags()}); + pushToken(elem, ParserGen::token::REGEX, BSONRegEx{elem.regex(), elem.regexFlags()}); break; case BSONType::DBRef: - pushToken(elem, - PipelineParserGen::token::DB_POINTER, - BSONDBRef{elem.dbrefNS(), elem.dbrefOID()}); + pushToken( + elem, ParserGen::token::DB_POINTER, BSONDBRef{elem.dbrefNS(), elem.dbrefOID()}); break; case BSONType::Code: - pushToken(elem, PipelineParserGen::token::JAVASCRIPT, BSONCode{elem.valueStringData()}); + pushToken(elem, ParserGen::token::JAVASCRIPT, BSONCode{elem.valueStringData()}); break; case BSONType::Symbol: - pushToken(elem, PipelineParserGen::token::SYMBOL, BSONSymbol{elem.valueStringData()}); + pushToken(elem, ParserGen::token::SYMBOL, BSONSymbol{elem.valueStringData()}); break; case BSONType::CodeWScope: { auto code = StringData{elem.codeWScopeCode(), static_cast<size_t>(elem.codeWScopeCodeLen()) - 1ull}; pushToken(elem, - PipelineParserGen::token::JAVASCRIPT_W_SCOPE, + ParserGen::token::JAVASCRIPT_W_SCOPE, BSONCodeWScope{code, elem.codeWScopeObject()}); break; } case NumberInt: if (elem.numberInt() == 0) - pushToken(elem, PipelineParserGen::token::INT_ZERO); + pushToken(elem, ParserGen::token::INT_ZERO); else if (elem.numberInt() == 1) - pushToken(elem, PipelineParserGen::token::INT_ONE); + pushToken(elem, ParserGen::token::INT_ONE); else if (elem.numberInt() == -1) - pushToken(elem, PipelineParserGen::token::INT_NEGATIVE_ONE); + pushToken(elem, ParserGen::token::INT_NEGATIVE_ONE); else - pushToken(elem, PipelineParserGen::token::INT_OTHER, elem.numberInt()); + pushToken(elem, ParserGen::token::INT_OTHER, elem.numberInt()); break; case BSONType::bsonTimestamp: - pushToken(elem, PipelineParserGen::token::TIMESTAMP, elem.timestamp()); + pushToken(elem, ParserGen::token::TIMESTAMP, elem.timestamp()); break; case NumberLong: if (elem.numberLong() == 0ll) - pushToken(elem, PipelineParserGen::token::LONG_ZERO); + pushToken(elem, ParserGen::token::LONG_ZERO); else if (elem.numberLong() == 1ll) - pushToken(elem, PipelineParserGen::token::LONG_ONE); + pushToken(elem, ParserGen::token::LONG_ONE); else if (elem.numberLong() == -1ll) - pushToken(elem, PipelineParserGen::token::LONG_NEGATIVE_ONE); + pushToken(elem, ParserGen::token::LONG_NEGATIVE_ONE); else - pushToken(elem, PipelineParserGen::token::LONG_OTHER, elem.numberLong()); + pushToken(elem, ParserGen::token::LONG_OTHER, elem.numberLong()); break; case NumberDecimal: if (elem.numberDecimal() == Decimal128::kNormalizedZero) - pushToken(elem, PipelineParserGen::token::DECIMAL_ZERO); + pushToken(elem, ParserGen::token::DECIMAL_ZERO); else if (elem.numberDecimal() == Decimal128(1)) { - pushToken(elem, PipelineParserGen::token::DECIMAL_ONE); + pushToken(elem, ParserGen::token::DECIMAL_ONE); } else if (elem.numberDecimal() == Decimal128(-1)) { - pushToken(elem, PipelineParserGen::token::DECIMAL_NEGATIVE_ONE); + pushToken(elem, ParserGen::token::DECIMAL_NEGATIVE_ONE); } else - pushToken(elem, PipelineParserGen::token::DECIMAL_OTHER, elem.numberDecimal()); + pushToken(elem, ParserGen::token::DECIMAL_OTHER, elem.numberDecimal()); break; case BSONType::MinKey: - pushToken(elem, PipelineParserGen::token::MIN_KEY, UserMinKey{}); + pushToken(elem, ParserGen::token::MIN_KEY, UserMinKey{}); break; case BSONType::MaxKey: - pushToken(elem, PipelineParserGen::token::MAX_KEY, UserMaxKey{}); + pushToken(elem, ParserGen::token::MAX_KEY, UserMaxKey{}); break; default: MONGO_UNREACHABLE; } } -BSONLexer::BSONLexer(BSONObj obj, PipelineParserGen::token_type startingToken) { - ScopedLocationTracker matchCtx{this, "filter"}; - pushToken("start", startingToken); - pushToken("start object", PipelineParserGen::token::START_OBJECT); - for (auto&& elem : obj) { - // Include field names in the object. - tokenize(elem, true); - } - pushToken("end object", PipelineParserGen::token::END_OBJECT); - - // Final token must indicate EOF. - pushToken("EOF", PipelineParserGen::token::END_OF_FILE); - - // Reset the position to use in yylex(). - _position = 0; -}; - -BSONLexer::BSONLexer(std::vector<BSONElement> pipeline, - PipelineParserGen::token_type startingToken) { - ScopedLocationTracker pipelineCtx{this, "pipeline"}; - pushToken("start", startingToken); - pushToken("start array", PipelineParserGen::token::START_ARRAY); - auto index = 0; - for (auto&& elem : pipeline) { - ScopedLocationTracker stageCtx{this, index++}; - // Don't include field names for stages of the pipeline (aka indexes of the pipeline array). - tokenize(elem, false); - } - pushToken("end array", PipelineParserGen::token::END_ARRAY); +BSONLexer::BSONLexer(BSONElement input) { + tokenize(input, true); // Final token must indicate EOF. - pushToken("EOF", PipelineParserGen::token::END_OF_FILE); + pushToken("EOF", ParserGen::token::END_OF_FILE); // Reset the position to use in yylex(). _position = 0; }; -PipelineParserGen::symbol_type yylex(mongo::BSONLexer& lexer) { +ParserGen::symbol_type yylex(mongo::BSONLexer& lexer) { return lexer.getNext(); } |