diff --git a/src/common/backend/parser/kwlookup.cpp b/src/common/backend/parser/kwlookup.cpp index ba028baee..0fb706114 100644 --- a/src/common/backend/parser/kwlookup.cpp +++ b/src/common/backend/parser/kwlookup.cpp @@ -1,90 +1,52 @@ -/* ------------------------------------------------------------------------- - * - * kwlookup.cpp - * lexical token lookup for key words in openGauss - * - * NB - this file is also used by ECPG and several frontend programs in - * src/bin/ including pg_dump and psql - * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/backend/parser/kwlookup.cpp - * - * ------------------------------------------------------------------------- - */ - -/* use c.h so this can be built as either frontend or backend */ -#include "c.h" - -#include - -#include "parser/keywords.h" - -/* - * ScanKeywordLookup - see if a given word is a keyword - * - * Returns a pointer to the ScanKeyword table entry, or NULL if no match. - * - * The match is done case-insensitively. Note that we deliberately use a - * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z', - * even if we are in a locale where tolower() would produce more or different - * translations. This is to conform to the SQL99 spec, which says that - * keywords are to be matched in this way even though non-keyword identifiers - * receive a different case-normalization mapping. - */ +//返回指向ScanKeyword表项的指针,如果不匹配则返回NULL。 + /* 匹配是不区分大小写的。注意,我们故意使用简化的大小写转换,只将'A'-' Z'翻译成'a'-' z',即使我们在tolower()会产生更多或不同的翻译。这是为了符合SQL99规范,该规范规定即使非关键字标识符接收不同的大小写规范化映射,也要以这种方式匹配关键字。*/ +//用于判断信息的关键字,从而将关键词返回为具体的token给程序 const ScanKeyword* ScanKeywordLookup(const char* text, const ScanKeyword* keywords, int num_keywords) { int len, i; char word[NAMEDATALEN] = {0}; const ScanKeyword* low = NULL; const ScanKeyword* high = NULL; - if (text == NULL) { return NULL; } - len = strlen(text); - /* We assume all keywords are shorter than NAMEDATALEN. */ + /* 我们假设所有关键字都比NAMEDATALEN短。 */ if (len >= NAMEDATALEN) { return NULL; } - /* - * Apply an ASCII-only downcasing. We must not use tolower() since it may - * produce the wrong translation in some locales (eg, Turkish). +应用仅限ascII的下标。我们一定不要使用tolower(),因为它可能在某些地区产生错误的翻译(如土耳其语)。 */ for (i = 0; i < len; i++) { char ch = text[i]; - if (ch >= 'A' && ch <= 'Z') { ch += 'a' - 'A'; } word[i] = ch; } word[len] = '\0'; - /* - * Now do a binary search using plain strcmp() comparison. + *使用strcmp()比较执行二进制搜索。 */ low = keywords; high = keywords + (num_keywords - 1); while (low <= high) { const ScanKeyword* middle = NULL; int difference; - middle = low + (high - low) / 2; difference = strcmp(middle->name, word); if (difference == 0) { return middle; - } else if (difference < 0) { + } + //如果middle->name比word短,返回-1 + else if (difference < 0) { low = middle + 1; - } else { + } + //如果middle->name比word长,返回1 + else { high = middle - 1; } } - return NULL; -} +} \ No newline at end of file diff --git a/src/common/backend/parser/scansup.cpp b/src/common/backend/parser/scansup.cpp index dc11a225d..a17ce787c 100644 --- a/src/common/backend/parser/scansup.cpp +++ b/src/common/backend/parser/scansup.cpp @@ -43,76 +43,57 @@ char* scanstr(const char* s) newStr = (char*)palloc(len + 1); /* string cannot get longer */ - for (i = 0, j = 0; i < len; i++) { - if (s[i] == '\'') { - /* - * Note: if scanner is working right, unescaped quotes can only - * appear in pairs, so there should be another character. - */ - i++; - newStr[j] = s[i]; - } else if (s[i] == '\\') { - i++; - switch (s[i]) { - case 'b': - newStr[j] = '\b'; - break; - case 'f': - newStr[j] = '\f'; - break; - case 'n': - newStr[j] = '\n'; - break; - case 'r': - newStr[j] = '\r'; - break; - case 't': - newStr[j] = '\t'; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': { - int k; - unsigned long octVal = 0; + for (i = 0, j = 0; i < len; i++) { + if (s[i] == '\'') { + i++; + newStr[j] = s[i];//说明不是转义字符 + } else if (s[i] == '\\') { + i++; + switch (s[i]) { + case 'b': + newStr[j] = '\b'; + break; + case 'f': + newStr[j] = '\f'; + break; + case 'n': + newStr[j] = '\n'; + break; + case 'r': + newStr[j] = '\r'; + break; + case 't': + newStr[j] = '\t'; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + int k; + unsigned long octVal = 0; + for (k = 0; s[i + k] >= '0' && s[i + k] <= '7' && k < 3; k++){ + octVal = (octVal << 3) + (s[i + k] - '0'); + } + i += k - 1; + newStr[j] = ((char)octVal); + } break; + default: + newStr[j] = s[i]; + break; + } /* switch */ + } /* s[i] == '\\' */ + else { + newStr[j] = s[i]; + } + j++; + } + newStr[j] = '\0'; - for (k = 0; s[i + k] >= '0' && s[i + k] <= '7' && k < 3; k++){ - octVal = (octVal << 3) + (s[i + k] - '0'); - } - i += k - 1; - newStr[j] = ((char)octVal); - } break; - default: - newStr[j] = s[i]; - break; - } /* switch */ - } /* s[i] == '\\' */ - else { - newStr[j] = s[i]; - } - j++; - } - newStr[j] = '\0'; - return newStr; -} - -/* - * downcase_truncate_identifier() --- do appropriate downcasing and - * truncation of an unquoted identifier. Optionally warn of truncation. - * - * Returns a palloc'd string containing the adjusted identifier. - * - * Note: in some usages the passed string is not null-terminated. - * - * Note: the API of this function is designed to allow for downcasing - * transformations that increase the string length, but we don't yet - * support that. If you want to implement it, you'll need to fix - * SplitIdentifierString() in utils/adt/varlena.c. - */ + //对未加引号的标识符进行适当的大小写转换和截断。可选的截断警告。 char* downcase_truncate_identifier(const char* ident, int len, bool warn) { char* result = NULL; @@ -180,15 +161,8 @@ void truncate_identifier(char* ident, int len, bool warn) } } -/* - * scanner_isspace() --- return TRUE if flex scanner considers char whitespace - * - * This should be used instead of the potentially locale-dependent isspace() - * function when it's important to match the lexer's behavior. - * - * In principle we might need similar functions for isalnum etc, but for the - * moment only isspace seems needed. */ +// 如果flex scanner识别出字符空白,则返回TRUE bool scanner_isspace(char ch) { /* This must match scan.l's list of {space} characters */