1 | #include <Common/StringUtils/StringUtils.h> |
---|---|
2 | #include <Parsers/CommonParsers.h> |
3 | #include <common/find_symbols.h> |
4 | |
5 | #include <string.h> /// strncmp, strncasecmp |
6 | |
7 | |
8 | namespace DB |
9 | { |
10 | |
11 | namespace ErrorCodes |
12 | { |
13 | extern const int LOGICAL_ERROR; |
14 | } |
15 | |
16 | |
17 | ParserKeyword::ParserKeyword(const char * s_) : s(s_) |
18 | { |
19 | } |
20 | |
21 | |
22 | const char * ParserKeyword::getName() const |
23 | { |
24 | return s; |
25 | } |
26 | |
27 | |
28 | bool ParserKeyword::parseImpl(Pos & pos, ASTPtr & /*node*/, Expected & expected) |
29 | { |
30 | if (pos->type != TokenType::BareWord) |
31 | return false; |
32 | |
33 | const char * current_word = s; |
34 | |
35 | size_t s_length = strlen(s); |
36 | if (!s_length) |
37 | throw Exception("Logical error: keyword cannot be empty string", ErrorCodes::LOGICAL_ERROR); |
38 | |
39 | const char * s_end = s + s_length; |
40 | |
41 | while (true) |
42 | { |
43 | expected.add(pos, current_word); |
44 | if (pos->type != TokenType::BareWord) |
45 | return false; |
46 | |
47 | const char * next_whitespace = find_first_symbols<' ', '\0'>(current_word, s_end); |
48 | size_t word_length = next_whitespace - current_word; |
49 | |
50 | if (word_length != pos->size()) |
51 | return false; |
52 | |
53 | if (strncasecmp(pos->begin, current_word, word_length)) |
54 | return false; |
55 | |
56 | ++pos; |
57 | |
58 | if (!*next_whitespace) |
59 | break; |
60 | |
61 | current_word = next_whitespace + 1; |
62 | } |
63 | |
64 | return true; |
65 | } |
66 | |
67 | } |
68 |