diff options
author | Antonin Kral <a.kral@bobek.cz> | 2010-01-31 08:32:52 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2010-01-31 08:32:52 +0100 |
commit | 4eefaf421bfeddf040d96a3dafb12e09673423d7 (patch) | |
tree | cb2e5ccc7f98158894f977ff131949da36673591 /db/minilex.h | |
download | mongodb-4eefaf421bfeddf040d96a3dafb12e09673423d7.tar.gz |
Imported Upstream version 1.3.1
Diffstat (limited to 'db/minilex.h')
-rw-r--r-- | db/minilex.h | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/db/minilex.h b/db/minilex.h new file mode 100644 index 0000000..ba8df26 --- /dev/null +++ b/db/minilex.h @@ -0,0 +1,160 @@ +// minilex.h +// mini js lexical analyzer. idea is to be dumb and fast. + +/** +* Copyright (C) 2008 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* 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 <http://www.gnu.org/licenses/>. +*/ + +namespace mongo { + +#if defined(_WIN32) + +} // namespace mongo + +#include <hash_map> +using namespace stdext; + +namespace mongo { + + typedef const char * MyStr; + struct less_str { + bool operator()(const MyStr & x, const MyStr & y) const { + if ( strcmp(x, y) > 0) + return true; + + return false; + } + }; + + typedef hash_map<const char*, int, hash_compare<const char *, less_str> > strhashmap; + +#else + +} // namespace mongo + +#include <ext/hash_map> + +namespace mongo { + + using namespace __gnu_cxx; + + typedef const char * MyStr; + struct eq_str { + bool operator()(const MyStr & x, const MyStr & y) const { + if ( strcmp(x, y) == 0) + return true; + + return false; + } + }; + + typedef hash_map<const char*, int, hash<const char *>, eq_str > strhashmap; + +#endif + + struct MiniLex { + strhashmap reserved; + bool ic[256]; // ic=Identifier Character + bool starter[256]; + + // dm: very dumb about comments and escaped quotes -- but we are faster then at least, + // albeit returning too much (which is ok for jsbobj current usage). + void grabVariables(char *code /*modified and must stay in scope*/, strhashmap& vars) { + char *p = code; + char last = 0; + while ( *p ) { + if ( starter[*p] ) { + char *q = p+1; + while ( *q && ic[*q] ) q++; + const char *identifier = p; + bool done = *q == 0; + *q = 0; + if ( !reserved.count(identifier) ) { + // we try to be smart about 'obj' but have to be careful as obj.obj + // can happen; this is so that nFields is right for simplistic where cases + // so we can stop scanning in jsobj when we find the field of interest. + if ( strcmp(identifier,"obj")==0 && p>code && p[-1] != '.' ) + ; + else + vars[identifier] = 1; + } + if ( done ) + break; + p = q + 1; + continue; + } + + if ( *p == '\'' ) { + p++; + while ( *p && *p != '\'' ) p++; + } + else if ( *p == '"' ) { + p++; + while ( *p && *p != '"' ) p++; + } + p++; + } + } + + MiniLex() { + strhashmap atest; + atest["foo"] = 3; + assert( atest.count("bar") == 0 ); + assert( atest.count("foo") == 1 ); + assert( atest["foo"] == 3 ); + + for ( int i = 0; i < 256; i++ ) { + ic[i] = starter[i] = false; + } + for ( int i = 'a'; i <= 'z'; i++ ) + ic[i] = starter[i] = true; + for ( int i = 'A'; i <= 'Z'; i++ ) + ic[i] = starter[i] = true; + for ( int i = '0'; i <= '9'; i++ ) + ic[i] = true; + for ( int i = 128; i < 256; i++ ) + ic[i] = starter[i] = true; + ic['$'] = starter['$'] = true; + ic['_'] = starter['_'] = true; + + reserved["break"] = true; + reserved["case"] = true; + reserved["catch"] = true; + reserved["continue"] = true; + reserved["default"] = true; + reserved["delete"] = true; + reserved["do"] = true; + reserved["else"] = true; + reserved["finally"] = true; + reserved["for"] = true; + reserved["function"] = true; + reserved["if"] = true; + reserved["in"] = true; + reserved["instanceof"] = true; + reserved["new"] = true; + reserved["return"] = true; + reserved["switch"] = true; + reserved["this"] = true; + reserved["throw"] = true; + reserved["try"] = true; + reserved["typeof"] = true; + reserved["var"] = true; + reserved["void"] = true; + reserved["while"] = true; + reserved["with "] = true; + } + }; + +} // namespace mongo |