You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
395 lines
8.8 KiB
395 lines
8.8 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
lexer.cxx
|
|
|
|
Abstract:
|
|
|
|
This module implements functions to recognize the tokens in the string
|
|
repressentation of the search filter. The format of the search filter
|
|
according to Minimal SQL grammar which is a subset of ANSI SQL 92.
|
|
|
|
Author:
|
|
|
|
Shankara Shastry [ShankSh] 13-Dec-1996
|
|
|
|
++*/
|
|
|
|
#include "lexer.hxx"
|
|
#include "macro.h"
|
|
|
|
DFA_STATE CLexer::_pStateTable[MAX_DFA_STATES][MAX_CHAR_CLASSES] = gStateTable;
|
|
|
|
WCHAR CLexer::_pKeywordTable[][MAX_KEYWORD_LEN] = gKWTable;
|
|
DWORD CLexer::_pKW2Token[] = gKW2Token;
|
|
|
|
DWORD CLexer::_pCharClassTable[] = gCharClassTable;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CLexer
|
|
//
|
|
// Synopsis: Constructor: Allocate memory for the pattern and initialize
|
|
//
|
|
// Arguments: szBuffer: pattern
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CLexer::CLexer(
|
|
LPWSTR szBuffer
|
|
):
|
|
_ptr(NULL),
|
|
_Buffer(NULL),
|
|
_dwEndofString(0),
|
|
_dwState(START_STATE),
|
|
_lexeme()
|
|
{
|
|
_bInitialized = FALSE;
|
|
if (!szBuffer || !*szBuffer) {
|
|
return;
|
|
}
|
|
_Buffer = (LPWSTR) AllocADsMem(
|
|
(wcslen(szBuffer)+1) * sizeof(WCHAR)
|
|
);
|
|
if(_Buffer)
|
|
wcscpy(_Buffer,
|
|
szBuffer
|
|
);
|
|
_ptr = _Buffer;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: GetNextToken
|
|
//
|
|
// Synopsis: Give the next valid token
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CLexer::GetNextToken(
|
|
LPWSTR *ppszToken,
|
|
LPDWORD pdwToken
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR wcNextChar;
|
|
DWORD dwActionId;
|
|
DFA_STATE dfaState;
|
|
DWORD dwStartState = _dwState;
|
|
// If there is no pattern
|
|
if(!_ptr) {
|
|
*pdwToken = TOKEN_END;
|
|
RRETURN (S_OK);
|
|
}
|
|
|
|
// Start forming the lexeme.
|
|
|
|
_lexeme.ResetLexeme();
|
|
|
|
*ppszToken = NULL;
|
|
*pdwToken = TOKEN_ERROR;
|
|
|
|
while (_dwState != STATE_ERROR && _dwState < FINAL_STATES_BEGIN) {
|
|
// Get the character class from the character and then index the
|
|
// state table
|
|
wcNextChar = NextChar();
|
|
dwActionId = _pStateTable[_dwState][GetCharClass(wcNextChar)].
|
|
dwActionId;
|
|
|
|
_dwState = _pStateTable[_dwState][GetCharClass(wcNextChar)].
|
|
dwNextState;
|
|
|
|
if(_dwState == STATE_ERROR) {
|
|
BAIL_ON_FAILURE (E_FAIL);
|
|
}
|
|
|
|
hr = PerformAction(_dwState,
|
|
wcNextChar,
|
|
dwActionId);
|
|
BAIL_ON_FAILURE (hr);
|
|
}
|
|
|
|
_bInitialized = TRUE;
|
|
|
|
if(*pdwToken == TOKEN_END)
|
|
RRETURN (S_OK);
|
|
|
|
*ppszToken = _lexeme.GetLexeme();
|
|
*pdwToken = GetTokenFromState(_dwState);
|
|
|
|
_dwStateSave = _dwState;
|
|
|
|
_dwState = START_STATE;
|
|
|
|
RRETURN (S_OK);
|
|
|
|
error:
|
|
RRETURN (hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: NextChar
|
|
//
|
|
// Synopsis: Returns the next chaarcter in the pattern
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
WCHAR
|
|
CLexer::NextChar()
|
|
{
|
|
if (_ptr == NULL || *_ptr == L'\0') {
|
|
_dwEndofString = TRUE;
|
|
return(L'\0');
|
|
}
|
|
return(*_ptr++);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: GetCurrentToken
|
|
//
|
|
// Synopsis: Give the current valid token, and do not advance unless
|
|
// it is the first token
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CLexer::GetCurrentToken(
|
|
LPWSTR *ppszToken,
|
|
LPDWORD pdwToken
|
|
)
|
|
{
|
|
if (!_bInitialized) {
|
|
HRESULT hr;
|
|
hr = GetNextToken(
|
|
ppszToken,
|
|
pdwToken
|
|
);
|
|
return hr;
|
|
} else {
|
|
*ppszToken = _lexeme.GetLexeme();
|
|
*pdwToken = GetTokenFromState(_dwStateSave);
|
|
return (S_OK);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: PushbackChar
|
|
//
|
|
// Synopsis: Puts back a character to the unrecognised pattern
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
CLexer::PushbackChar()
|
|
{
|
|
if (_dwEndofString) {
|
|
return;
|
|
}
|
|
_ptr--;
|
|
|
|
}
|
|
|
|
HRESULT
|
|
CLexer::PerformAction(
|
|
DWORD dwCurrState,
|
|
WCHAR wcCurrChar,
|
|
DWORD dwActionId
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch(dwActionId) {
|
|
case ACTION_PUSHBACK_CHAR:
|
|
PushbackChar();
|
|
break;
|
|
case ACTION_IGNORE_ESCAPECHAR:
|
|
break;
|
|
case ACTION_DEFAULT:
|
|
hr = _lexeme.PushNextChar(wcCurrChar);
|
|
BAIL_ON_FAILURE(hr);
|
|
break;
|
|
}
|
|
|
|
if(_dwState >= FINAL_STATES_BEGIN)
|
|
_lexeme.PushNextChar(L'\0');
|
|
|
|
error:
|
|
RRETURN (hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CLexer::GetTokenFromState
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
inline DWORD
|
|
CLexer::GetTokenFromState(
|
|
DWORD dwCurrState
|
|
)
|
|
{
|
|
DWORD dwToken = dwCurrState - FINAL_STATES_BEGIN;
|
|
LPWSTR pszToken = _lexeme.GetLexeme();
|
|
|
|
if(dwToken != TOKEN_USER_DEFINED_NAME)
|
|
return dwToken;
|
|
|
|
for (int i=0; _pKeywordTable[i][0] != '\0'; i++) {
|
|
if(!_wcsicmp(pszToken, _pKeywordTable[i]))
|
|
return (_pKW2Token[i]);
|
|
}
|
|
|
|
return (TOKEN_USER_DEFINED_NAME);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: ~CLexer
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CLexer::~CLexer()
|
|
{
|
|
if( _Buffer )
|
|
FreeADsMem (_Buffer);
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CLexeme
|
|
//
|
|
// Synopsis: Constructor: Allocate memory for the pattern and initialize
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CLexeme::CLexeme(
|
|
):
|
|
_dwMaxLength(0),
|
|
_dwIndex(0)
|
|
{
|
|
_pszLexeme = (LPWSTR) AllocADsMem(LEXEME_UNIT_LENGTH * sizeof(WCHAR));
|
|
if(_pszLexeme)
|
|
_dwMaxLength = LEXEME_UNIT_LENGTH;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: ~CLexeme
|
|
//
|
|
// Synopsis: Destructor
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CLexeme::~CLexeme(
|
|
)
|
|
{
|
|
if(_pszLexeme)
|
|
FreeADsMem(_pszLexeme);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: PushNextChar
|
|
//
|
|
// Synopsis: Add the next character after making sure there is enough memory
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 07-09-96 ShankSh Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CLexeme::PushNextChar(
|
|
WCHAR wcNextChar
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if(_dwIndex >= _dwMaxLength)
|
|
{
|
|
LPWSTR pszNewLexeme = (LPWSTR) ReallocADsMem(
|
|
_pszLexeme,
|
|
_dwMaxLength * sizeof(WCHAR),
|
|
(_dwMaxLength + LEXEME_UNIT_LENGTH)* sizeof(WCHAR)
|
|
);
|
|
if (!pszNewLexeme) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
_pszLexeme = pszNewLexeme;
|
|
_dwMaxLength += LEXEME_UNIT_LENGTH;
|
|
}
|
|
|
|
_pszLexeme[_dwIndex++] = wcNextChar;
|
|
|
|
error:
|
|
RRETURN (hr);
|
|
|
|
}
|