1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include "parser_call_stack.h"
#include "grammar.h"
#include <util/generic/vector.h>
#include <util/generic/algorithm.h>
#include <util/generic/yexception.h>
#include <ranges>
#define DEBUG_SYMBOLIZE_STACK(stack) \
auto debug_symbolized_##stack = Symbolized(stack)
namespace NSQLComplete {
const TVector<TRuleId> KeywordRules = {
RULE(Keyword),
RULE(Keyword_expr_uncompat),
RULE(Keyword_table_uncompat),
RULE(Keyword_select_uncompat),
RULE(Keyword_alter_uncompat),
RULE(Keyword_in_uncompat),
RULE(Keyword_window_uncompat),
RULE(Keyword_hint_uncompat),
RULE(Keyword_as_compat),
RULE(Keyword_compat),
};
const TVector<TRuleId> PragmaNameRules = {
RULE(Opt_id_prefix_or_type),
RULE(An_id),
};
const TVector<TRuleId> TypeNameRules = {
RULE(Type_name_simple),
RULE(An_id_or_type),
};
const TVector<TRuleId> FunctionNameRules = {
RULE(Id_expr),
RULE(An_id_or_type),
RULE(Id_or_type),
};
const TVector<TRuleId> HintNameRules = {
RULE(Id_hint),
RULE(An_id),
};
TVector<std::string> Symbolized(const TParserCallStack& stack) {
const ISqlGrammar& grammar = GetSqlGrammar();
TVector<std::string> symbolized;
symbolized.reserve(stack.size());
for (const TRuleId& rule : stack) {
symbolized.emplace_back(grammar.SymbolizedRule(rule));
}
return symbolized;
}
bool EndsWith(const TParserCallStack& suffix, const TParserCallStack& stack) {
if (stack.size() < suffix.size()) {
return false;
}
const size_t prefixSize = stack.size() - suffix.size();
return Equal(std::begin(stack) + prefixSize, std::end(stack), std::begin(suffix));
}
bool Contains(const TParserCallStack& sequence, const TParserCallStack& stack) {
return !std::ranges::search(stack, sequence).empty();
}
bool ContainsRule(TRuleId rule, const TParserCallStack& stack) {
return Find(stack, rule) != std::end(stack);
}
bool IsLikelyPragmaStack(const TParserCallStack& stack) {
return EndsWith({RULE(Pragma_stmt), RULE(Opt_id_prefix_or_type)}, stack) ||
EndsWith({RULE(Pragma_stmt), RULE(An_id)}, stack);
}
bool IsLikelyTypeStack(const TParserCallStack& stack) {
return EndsWith({RULE(Type_name_simple)}, stack) ||
(Contains({RULE(Invoke_expr),
RULE(Named_expr_list),
RULE(Named_expr),
RULE(Expr)}, stack) &&
EndsWith({RULE(Atom_expr), RULE(An_id_or_type)}, stack));
}
bool IsLikelyFunctionStack(const TParserCallStack& stack) {
return EndsWith({RULE(Unary_casual_subexpr), RULE(Id_expr)}, stack) ||
EndsWith({RULE(Unary_casual_subexpr),
RULE(Atom_expr),
RULE(An_id_or_type)}, stack) ||
EndsWith({RULE(Atom_expr), RULE(Id_or_type)}, stack);
}
bool IsLikelyHintStack(const TParserCallStack& stack) {
return ContainsRule(RULE(Id_hint), stack) ||
Contains({RULE(External_call_param), RULE(An_id)}, stack);
}
TMaybe<EStatementKind> StatementKindOf(const TParserCallStack& stack) {
for (TRuleId rule : std::ranges::views::reverse(stack)) {
if (rule == RULE(Process_core) || rule == RULE(Reduce_core) || rule == RULE(Select_core)) {
return EStatementKind::Select;
}
if (rule == RULE(Into_table_stmt)) {
return EStatementKind::Insert;
}
}
return Nothing();
}
std::unordered_set<TRuleId> GetC3PreferredRules() {
std::unordered_set<TRuleId> preferredRules;
preferredRules.insert(std::begin(KeywordRules), std::end(KeywordRules));
preferredRules.insert(std::begin(PragmaNameRules), std::end(PragmaNameRules));
preferredRules.insert(std::begin(TypeNameRules), std::end(TypeNameRules));
preferredRules.insert(std::begin(FunctionNameRules), std::end(FunctionNameRules));
return preferredRules;
}
} // namespace NSQLComplete
|