diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/usql/UQ_LEXER.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/usql/UQ_LEXER.CPP Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,360 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// SQL parser tokeniser +// +// + +#include "UQ_STD.H" + +// optimised tables for ASCII character set + +const TUint8 KAlpha=0x1; +const TUint8 KDigitOr_=0x2; + +const TUint8 KCharAttrib[]= + { + KDigitOr_,KDigitOr_,KDigitOr_,KDigitOr_,KDigitOr_,KDigitOr_,KDigitOr_,KDigitOr_, + KDigitOr_,KDigitOr_,0,0,0,0,0,0, + 0,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha, + KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha, + KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha, + KAlpha,KAlpha,KAlpha,0,0,0,0,KDigitOr_, + 0,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha, + KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha, + KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha,KAlpha, + KAlpha,KAlpha,KAlpha + }; + +#define ISALPHA(aChar) (TUint(aChar-'0')<=TUint('z'-'0') && KCharAttrib[aChar-'0']&KAlpha) +#define ISALPHA_DIGIT_OR_(aChar) (TUint(aChar-'0')<=TUint('z'-'0') && KCharAttrib[aChar-'0']&(KAlpha|KDigitOr_)) +#define LCASE(aChar) (aChar|0x20) + +// The keywords +// These are always stored as ASCII because DBMS has its own + +const TInt KMaxKeywordLength=9; + +static const TText8 KSqlKeywords[][KMaxKeywordLength+1]= + { +#define KEYWORD(s) #s +#include "UQ_KEYWD.H" +#undef KEYWORD + }; +const TInt KSqlKeywordCount=sizeof(KSqlKeywords)/sizeof(*KSqlKeywords); + +#if defined(_ASSERTIONS) +TInt CheckKeywords() +// +// ensure that the keyword table is in alphabetical order +// + { + for (TInt ii=1;iil) + { + TInt m=(l+r)>>1; + TInt k=CompareKeyword(m,aToken.Literal()); + if (k>0) + r=m; + else if (k<0) + l=m+1; + else + return TSqlKeyword(m); // keyword + } + } + // identifier + return ESqlNotKeyword; + } + +TSqlLexer::TSqlLexer(const TDesC& aSql) + : iNext(aSql.Ptr()),iEnd(iNext+aSql.Length()) + { + __ASSERT(CheckKeywords()); + } + +TSqlTokenType TSqlLexer::GetIdentifier(TSqlToken& aToken) +// +// Get a keyword or identifier. Do not resolve a keyword at this stage +// + { + const TText* end=iEnd; + const TText* next=iNext-1; + while (++next=10u) + return KErrGeneral; // no digits at all + TUint val32=c; + while (++ptr=10u) + break; + if (val32>KPreMultiplyLimit32) + goto overflow64; // will not fit into 32 bit arithmetic + val32*=10; + val32+=c; + } +// we have result, just set the sign and finish + aVal=val32; + goto checksign; +// +// continue the accumulation with a 64-bit integer +overflow64: + aVal=val32; + for (;;) + { + I64MUL10(aVal); + aVal+=c; + if (++ptr==end) + break; + c=*ptr-'0'; + if (c>=10u) + break; + if (I64HIGH(aVal)>KPreMultiplyLimit64) + return KErrOverflow; // the value is certain to overflow + } + if (I64HIGH(aVal)&0x80000000u) + { // greater than the "half way mark" + if (!sign) + return KErrOverflow; + if (I64LOW(aVal)!=0) + return KErrOverflow; + } +checksign: + iNext=ptr; + if (sign) + aVal=-aVal; + return KErrNone; + } + +TSqlTokenType TSqlLexer::GetNumber(TSqlToken& aToken) + { + const TText* mark=--iNext; // rewind past initial character + // attempt to parse a integer + TInt r=GetInteger(aToken.iLiteral.SetInt()); + if (r==KErrNone) + { + if (iNext') + { + iNext=ptr; + return ESqlNotEqual; + } + return ESqlLess; + } + case '>': + { + ch=*ptr++; + if (ch=='=') + { + iNext=ptr; + return ESqlGreaterEqual; + } + return ESqlGreater; + } + default: + break; + } + if (ISALPHA(ch)) + return GetIdentifier(aToken); // keyword or identifier + TChar cc(ch); + if (cc.IsAlpha()) + return GetIdentifier(aToken); // keyword or identifier + if (!cc.IsSpace()) + return SqlError(); + } + } + +const TText* TSqlLexer::Next() const + { + return iNext; + } +void TSqlLexer::Set(const TText* aNext) + { + iNext = aNext ; + }