Source code of Windows XP (NT5)
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.

394 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. lexer.cxx
  5. Abstract:
  6. This module implements functions to recognize the tokens in the string
  7. repressentation of the search filter. The format of the search filter
  8. according to Minimal SQL grammar which is a subset of ANSI SQL 92.
  9. Author:
  10. Shankara Shastry [ShankSh] 13-Dec-1996
  11. ++*/
  12. #include "lexer.hxx"
  13. #include "macro.h"
  14. DFA_STATE CLexer::_pStateTable[MAX_DFA_STATES][MAX_CHAR_CLASSES] = gStateTable;
  15. WCHAR CLexer::_pKeywordTable[][MAX_KEYWORD_LEN] = gKWTable;
  16. DWORD CLexer::_pKW2Token[] = gKW2Token;
  17. DWORD CLexer::_pCharClassTable[] = gCharClassTable;
  18. //+---------------------------------------------------------------------------
  19. // Function: CLexer
  20. //
  21. // Synopsis: Constructor: Allocate memory for the pattern and initialize
  22. //
  23. // Arguments: szBuffer: pattern
  24. //
  25. // Returns:
  26. //
  27. // Modifies:
  28. //
  29. // History: 07-09-96 ShankSh Created.
  30. //
  31. //----------------------------------------------------------------------------
  32. CLexer::CLexer(
  33. LPWSTR szBuffer
  34. ):
  35. _ptr(NULL),
  36. _Buffer(NULL),
  37. _dwEndofString(0),
  38. _dwState(START_STATE),
  39. _lexeme()
  40. {
  41. _bInitialized = FALSE;
  42. if (!szBuffer || !*szBuffer) {
  43. return;
  44. }
  45. _Buffer = (LPWSTR) AllocADsMem(
  46. (wcslen(szBuffer)+1) * sizeof(WCHAR)
  47. );
  48. if(_Buffer)
  49. wcscpy(_Buffer,
  50. szBuffer
  51. );
  52. _ptr = _Buffer;
  53. }
  54. //+---------------------------------------------------------------------------
  55. // Function: GetNextToken
  56. //
  57. // Synopsis: Give the next valid token
  58. //
  59. // Arguments:
  60. //
  61. // Returns:
  62. //
  63. // Modifies:
  64. //
  65. // History: 07-09-96 ShankSh Created.
  66. //
  67. //----------------------------------------------------------------------------
  68. HRESULT
  69. CLexer::GetNextToken(
  70. LPWSTR *ppszToken,
  71. LPDWORD pdwToken
  72. )
  73. {
  74. HRESULT hr = S_OK;
  75. WCHAR wcNextChar;
  76. DWORD dwActionId;
  77. DFA_STATE dfaState;
  78. DWORD dwStartState = _dwState;
  79. // If there is no pattern
  80. if(!_ptr) {
  81. *pdwToken = TOKEN_END;
  82. RRETURN (S_OK);
  83. }
  84. // Start forming the lexeme.
  85. _lexeme.ResetLexeme();
  86. *ppszToken = NULL;
  87. *pdwToken = TOKEN_ERROR;
  88. while (_dwState != STATE_ERROR && _dwState < FINAL_STATES_BEGIN) {
  89. // Get the character class from the character and then index the
  90. // state table
  91. wcNextChar = NextChar();
  92. dwActionId = _pStateTable[_dwState][GetCharClass(wcNextChar)].
  93. dwActionId;
  94. _dwState = _pStateTable[_dwState][GetCharClass(wcNextChar)].
  95. dwNextState;
  96. if(_dwState == STATE_ERROR) {
  97. BAIL_ON_FAILURE (E_FAIL);
  98. }
  99. hr = PerformAction(_dwState,
  100. wcNextChar,
  101. dwActionId);
  102. BAIL_ON_FAILURE (hr);
  103. }
  104. _bInitialized = TRUE;
  105. if(*pdwToken == TOKEN_END)
  106. RRETURN (S_OK);
  107. *ppszToken = _lexeme.GetLexeme();
  108. *pdwToken = GetTokenFromState(_dwState);
  109. _dwStateSave = _dwState;
  110. _dwState = START_STATE;
  111. RRETURN (S_OK);
  112. error:
  113. RRETURN (hr);
  114. }
  115. //+---------------------------------------------------------------------------
  116. // Function: NextChar
  117. //
  118. // Synopsis: Returns the next chaarcter in the pattern
  119. //
  120. // Arguments:
  121. //
  122. // Returns:
  123. //
  124. // Modifies:
  125. //
  126. // History: 07-09-96 ShankSh Created.
  127. //
  128. //----------------------------------------------------------------------------
  129. WCHAR
  130. CLexer::NextChar()
  131. {
  132. if (_ptr == NULL || *_ptr == L'\0') {
  133. _dwEndofString = TRUE;
  134. return(L'\0');
  135. }
  136. return(*_ptr++);
  137. }
  138. //+---------------------------------------------------------------------------
  139. // Function: GetCurrentToken
  140. //
  141. // Synopsis: Give the current valid token, and do not advance unless
  142. // it is the first token
  143. //
  144. // Arguments:
  145. //
  146. // Returns:
  147. //
  148. // Modifies:
  149. //
  150. // History: 07-09-96 ShankSh Created.
  151. //
  152. //----------------------------------------------------------------------------
  153. HRESULT
  154. CLexer::GetCurrentToken(
  155. LPWSTR *ppszToken,
  156. LPDWORD pdwToken
  157. )
  158. {
  159. if (!_bInitialized) {
  160. HRESULT hr;
  161. hr = GetNextToken(
  162. ppszToken,
  163. pdwToken
  164. );
  165. return hr;
  166. } else {
  167. *ppszToken = _lexeme.GetLexeme();
  168. *pdwToken = GetTokenFromState(_dwStateSave);
  169. return (S_OK);
  170. }
  171. }
  172. //+---------------------------------------------------------------------------
  173. // Function: PushbackChar
  174. //
  175. // Synopsis: Puts back a character to the unrecognised pattern
  176. //
  177. // Arguments:
  178. //
  179. // Returns:
  180. //
  181. // Modifies:
  182. //
  183. // History: 07-09-96 ShankSh Created.
  184. //
  185. //----------------------------------------------------------------------------
  186. void
  187. CLexer::PushbackChar()
  188. {
  189. if (_dwEndofString) {
  190. return;
  191. }
  192. _ptr--;
  193. }
  194. HRESULT
  195. CLexer::PerformAction(
  196. DWORD dwCurrState,
  197. WCHAR wcCurrChar,
  198. DWORD dwActionId
  199. )
  200. {
  201. HRESULT hr = S_OK;
  202. switch(dwActionId) {
  203. case ACTION_PUSHBACK_CHAR:
  204. PushbackChar();
  205. break;
  206. case ACTION_IGNORE_ESCAPECHAR:
  207. break;
  208. case ACTION_DEFAULT:
  209. hr = _lexeme.PushNextChar(wcCurrChar);
  210. BAIL_ON_FAILURE(hr);
  211. break;
  212. }
  213. if(_dwState >= FINAL_STATES_BEGIN)
  214. _lexeme.PushNextChar(L'\0');
  215. error:
  216. RRETURN (hr);
  217. }
  218. //+---------------------------------------------------------------------------
  219. // Function: CLexer::GetTokenFromState
  220. //
  221. // Synopsis:
  222. //
  223. // Arguments:
  224. //
  225. // Returns:
  226. //
  227. // Modifies:
  228. //
  229. // History: 07-09-96 ShankSh Created.
  230. //
  231. //----------------------------------------------------------------------------
  232. inline DWORD
  233. CLexer::GetTokenFromState(
  234. DWORD dwCurrState
  235. )
  236. {
  237. DWORD dwToken = dwCurrState - FINAL_STATES_BEGIN;
  238. LPWSTR pszToken = _lexeme.GetLexeme();
  239. if(dwToken != TOKEN_USER_DEFINED_NAME)
  240. return dwToken;
  241. for (int i=0; _pKeywordTable[i][0] != '\0'; i++) {
  242. if(!_wcsicmp(pszToken, _pKeywordTable[i]))
  243. return (_pKW2Token[i]);
  244. }
  245. return (TOKEN_USER_DEFINED_NAME);
  246. }
  247. //+---------------------------------------------------------------------------
  248. // Function: ~CLexer
  249. //
  250. // Synopsis:
  251. //
  252. // Arguments:
  253. //
  254. // Returns:
  255. //
  256. // Modifies:
  257. //
  258. // History: 07-09-96 ShankSh Created.
  259. //
  260. //----------------------------------------------------------------------------
  261. CLexer::~CLexer()
  262. {
  263. if( _Buffer )
  264. FreeADsMem (_Buffer);
  265. }
  266. //+---------------------------------------------------------------------------
  267. // Function: CLexeme
  268. //
  269. // Synopsis: Constructor: Allocate memory for the pattern and initialize
  270. //
  271. // Arguments:
  272. //
  273. // Returns:
  274. //
  275. // Modifies:
  276. //
  277. // History: 07-09-96 ShankSh Created.
  278. //
  279. //----------------------------------------------------------------------------
  280. CLexeme::CLexeme(
  281. ):
  282. _dwMaxLength(0),
  283. _dwIndex(0)
  284. {
  285. _pszLexeme = (LPWSTR) AllocADsMem(LEXEME_UNIT_LENGTH * sizeof(WCHAR));
  286. if(_pszLexeme)
  287. _dwMaxLength = LEXEME_UNIT_LENGTH;
  288. }
  289. //+---------------------------------------------------------------------------
  290. // Function: ~CLexeme
  291. //
  292. // Synopsis: Destructor
  293. //
  294. // Arguments:
  295. //
  296. // Returns:
  297. //
  298. // Modifies:
  299. //
  300. // History: 07-09-96 ShankSh Created.
  301. //
  302. //----------------------------------------------------------------------------
  303. CLexeme::~CLexeme(
  304. )
  305. {
  306. if(_pszLexeme)
  307. FreeADsMem(_pszLexeme);
  308. }
  309. //+---------------------------------------------------------------------------
  310. // Function: PushNextChar
  311. //
  312. // Synopsis: Add the next character after making sure there is enough memory
  313. //
  314. // Arguments:
  315. //
  316. // Returns:
  317. //
  318. // Modifies:
  319. //
  320. // History: 07-09-96 ShankSh Created.
  321. //
  322. //----------------------------------------------------------------------------
  323. HRESULT
  324. CLexeme::PushNextChar(
  325. WCHAR wcNextChar
  326. )
  327. {
  328. HRESULT hr = S_OK;
  329. if(_dwIndex >= _dwMaxLength)
  330. {
  331. _pszLexeme = (LPWSTR) ReallocADsMem(
  332. _pszLexeme,
  333. _dwMaxLength * sizeof(WCHAR),
  334. (_dwMaxLength + LEXEME_UNIT_LENGTH)* sizeof(WCHAR)
  335. );
  336. if (!_pszLexeme) {
  337. hr = E_OUTOFMEMORY;
  338. BAIL_ON_FAILURE(hr);
  339. }
  340. _dwMaxLength += LEXEME_UNIT_LENGTH;
  341. }
  342. _pszLexeme[_dwIndex++] = wcNextChar;
  343. error:
  344. RRETURN (hr);
  345. }