1
+ // Licensed to Cloudera, Inc. under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. Cloudera, Inc. licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+
17
+ %lex
18
+ %x singleQuote doubleQuote
19
+ %%
20
+
21
+ \s + { return ' WS' }
22
+
23
+ '\u2020 ' { parser .yy .cursorFound = yylloc; return ' CURSOR' ; }
24
+
25
+ [a-zA-Z] + [:] { return ' FACET' }
26
+
27
+ \' { this .begin (' singleQuote' ); return ' QUOTE' ; }
28
+
29
+ <singleQuote >(?:\\ ['] | [^ '] )+ {
30
+ if (parser .handleQuotedValueWithCursor (this , yytext , yylloc, ' \' ' )) {
31
+ return ' PARTIAL_VALUE' ;
32
+ }
33
+ return ' VALUE' ;
34
+ }
35
+
36
+ <singleQuote >\' { this .popState (); return ' QUOTE' ; }
37
+
38
+ \" { this .begin (' doubleQuote' ); return ' QUOTE' ; }
39
+
40
+ <doubleQuote >(?:\\ ["] | [^ "] )+ {
41
+ if (parser .handleQuotedValueWithCursor (this , yytext , yylloc, ' "' )) {
42
+ return ' PARTIAL_VALUE' ;
43
+ }
44
+ return ' VALUE' ;
45
+ }
46
+
47
+ <doubleQuote >\" { this .popState (); return ' QUOTE' ; }
48
+
49
+ [^ "'\s \u2020 ] + { return ' TEXT' ; }
50
+
51
+ <<EOF>> { return ' EOF' ; }
52
+
53
+ /lex
54
+
55
+ %start GlobalSearchAutocomplete
56
+
57
+ %%
58
+
59
+ GlobalSearchAutocomplete
60
+ : OptionalWhitespace SearchParts OptionalWhitespace 'EOF'
61
+ {
62
+ return $2 ;
63
+ }
64
+ | OptionalWhitespace SearchParts_EDIT 'EOF'
65
+ {
66
+ if (! $2 .facets ) {
67
+ $2 .facets = {};
68
+ }
69
+ if (! $2 .text ) {
70
+ $2 .text = [];
71
+ }
72
+ return $2 ;
73
+ }
74
+ | OptionalWhitespace 'EOF'
75
+ {
76
+ return { facets: {}, text: [] };
77
+ }
78
+ ;
79
+
80
+ SearchParts
81
+ : SearchPart
82
+ | SearchParts WS SearchPart
83
+ {
84
+ parser .mergeFacets ($1 , $3 );
85
+ parser .mergeText ($1 , $3 );
86
+ }
87
+ ;
88
+
89
+ SearchParts_EDIT
90
+ : SearchPart_EDIT
91
+ | SearchParts WS SearchPart_EDIT
92
+ {
93
+ parser .mergeFacets ($1 , $3 );
94
+ parser .mergeText ($1 , $3 );
95
+ $$ = $3 ;
96
+ $$ .text = $1 .text ;
97
+ $$ .facets = $1 .facets ;
98
+ }
99
+ | SearchPart_EDIT WS SearchParts
100
+ {
101
+ $$ = $1 ;
102
+ parser .mergeFacets ($$ , $3 );
103
+ parser .mergeText ($$ , $3 );
104
+ }
105
+ | SearchParts WS SearchPart_EDIT WS SearchParts
106
+ {
107
+ parser .mergeFacets ($1 , $3 );
108
+ parser .mergeFacets ($1 , $5 );
109
+ parser .mergeText ($1 , $3 );
110
+ parser .mergeText ($1 , $5 );
111
+ $$ = $3 ;
112
+ $$ .text = $1 .text ;
113
+ $$ .facets = $1 .facets ;
114
+ }
115
+ ;
116
+
117
+ SearchPart
118
+ : Facet --> { text: [], facets: $1 .facets }
119
+ | FreeText --> { text: [$1 ], facets: {} }
120
+ ;
121
+
122
+ SearchPart_EDIT
123
+ : Facet_EDIT
124
+ | FreeText_EDIT
125
+ ;
126
+
127
+ Facet
128
+ : 'FACET' OptionalWhitespace FreeText
129
+ {
130
+ var facet = {};
131
+ var facetName = $1 .substring (0 , $1 .length - 1 ).toLowerCase ();
132
+ facet[facetName] = {};
133
+ facet[facetName][$3 .toLowerCase ()] = true ;
134
+ $$ = { facets: facet };
135
+ }
136
+ ;
137
+
138
+ Facet_EDIT
139
+ : 'FACET' OptionalWhitespace 'CURSOR' --> { suggestFacetValues: $1 .substring (0 , $1 .length - 1 ).toLowerCase () }
140
+ | 'FACET' OptionalWhitespace FreeText 'CURSOR'
141
+ {
142
+ var facet = {};
143
+ var facetName = $1 .substring (0 , $1 .length - 1 ).toLowerCase ();
144
+ facet[facetName] = {};
145
+ facet[facetName][$3 .toLowerCase ()] = true ;
146
+ $$ = { suggestFacetValues: facetName, facets: facet }
147
+ }
148
+ ;
149
+
150
+ FreeText
151
+ : 'TEXT'
152
+ | QuotedValue
153
+ ;
154
+
155
+ FreeText_EDIT
156
+ : 'CURSOR' --> { suggestFacets: true , suggestResults: true }
157
+ | 'CURSOR' 'TEXT' --> { suggestFacets: true , suggestResults: true , text: [$2 ] }
158
+ | 'TEXT' 'CURSOR' 'TEXT' --> { suggestFacets: true , suggestResults: true , text: [$1 + $3 ] }
159
+ | 'TEXT' 'CURSOR' --> { suggestFacets: true , suggestResults: true , text: [$1 ] }
160
+ | QuotedValue_EDIT
161
+ ;
162
+
163
+ QuotedValue
164
+ : 'QUOTE' 'VALUE' 'QUOTE' --> $2
165
+ | 'QUOTE' 'QUOTE' --> ' '
166
+ ;
167
+
168
+ QuotedValue_EDIT
169
+ : 'QUOTE' 'PARTIAL_VALUE' --> $2
170
+ ;
171
+
172
+ OptionalWhitespace
173
+ :
174
+ | WS
175
+ ;
176
+
177
+ %%
178
+
179
+ SqlParseSupport .initGlobalSearchParser (parser);
0 commit comments