forked from eranif/codelite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammer.y
263 lines (228 loc) · 5.86 KB
/
grammer.y
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
%{
// Copyright Eran Ifrah(c)
%}
%{
#include <string>
#include <stdio.h>
#include <vector>
#include "clang_output_parser_api.h"
#define YYSTYPE std::string
#define YYDEBUG 0 /* get the pretty debugging code to compile*/
#ifdef yylex
#undef yylex
#define yylex clang_yylex
#endif
extern int clang_yylex();
extern void clang_yyless(int count);
int clang_result_parse();
/** defined in grammer.l **/
extern bool clang_set_lexer_input(const std::string &in);
extern const std::string& clang_lex_get_string();
extern void clang_lex_clean();
/** the parser entry point **/
void clang_parse_string(const std::string& str);
void clang_result_error(char*);
/** read the signature **/
void clang_read_signature();
void clang_read_type_name(std::string &store);
void clang_read_entry_name(std::string &store);
/** holds the last signature read **/
static ClangEntry clang_entry;
static ClangEntryVector clangEntryVector;
extern std::string clang_result_lval;
%}
%token CLANG_COMPLETION
%token CLANG_HIDDEN
%token CLANG_DELIM_OPEN
%token CLANG_DELIM_CLOSE
%token CLANG_ARG_DELIM_OPEN
%token CLANG_ARG_DELIM_CLOSE
%token CLANG_ARG_OPT_DELIM_OPEN
%token CLANG_ARG_OPT_DELIM_CLOSE
%token CLANG_STAR
%token CLANG_AMP
%token CLANG_TILDE
%token CLANG_ENUM
%token CLANG_ANONYMOUS
%token CLANG_CLCL
%token CLANG_OP_ASSIGN
%token CLANG_OP_DOTstar
%token CLANG_OP_ARROW
%token CLANG_OP_ARROWstar
%token CLANG_OP_ICR
%token CLANG_OP_DECR
%token CLANG_OP_LS
%token CLANG_OP_RS
%token CLANG_OP_LE
%token CLANG_OP_GE
%token CLANG_OP_EQ
%token CLANG_OP_NE
%token CLANG_ELLIPSIS
%token CLANG_NAME
%token CLANG_OPERATOR
%%
parse: completion_output
| parse completion_output
;
completion_output: {clang_entry.reset();} completion_entry
| error {
//printf("CodeLite: syntax error, unexpected token '%s' found\n", clang_lex_get_string().c_str());
}
;
/* COMPLETION: AddPendingEvent : [#void#][#wxEvtHandler::#]AddPendingEvent(<#wxEvent &event#>) */
/* COMPLETION: argc : [#int#][#wxAppConsole::#]argc */
completion_entry: CLANG_COMPLETION ':' entry_name ':' type_name scope entry_name function_part
{
bool is_func = !clang_entry.signature.empty();
clang_entry.parent = $6;
clang_entry.type_name = is_func ? std::string() : clang_entry.tmp;
clang_entry.return_value = is_func ? clang_entry.tmp : std::string();
if (clang_entry.type == ClangEntry::TypeUnknown) {
if(is_func)
clang_entry.type = ClangEntry::TypeMethod;
else
clang_entry.type = ClangEntry::TypeVariable;
}
clangEntryVector.push_back(clang_entry);
}
;
any_operator: CLANG_OP_ARROW {$$ = $1;}
| CLANG_OP_ARROWstar {$$ = $1;}
| CLANG_OP_ASSIGN {$$ = $1;}
| CLANG_OP_DECR {$$ = $1;}
| CLANG_OP_DOTstar {$$ = $1;}
| CLANG_OP_EQ {$$ = $1;}
| CLANG_OP_GE {$$ = $1;}
| CLANG_OP_ICR {$$ = $1;}
| CLANG_OP_LE {$$ = $1;}
| CLANG_OP_LS {$$ = $1;}
| CLANG_OP_NE {$$ = $1;}
| CLANG_OP_RS {$$ = $1;}
| '('')' {$$ = "()";}
| '['']' {$$ = "[]";}
;
entry_name: /* empty */ { $$ = ""; }
| CLANG_NAME
{
clang_entry.name.clear();
clang_entry.name = $1;
}
| CLANG_OPERATOR any_operator
{
clang_entry.name.clear();
clang_entry.name = $1 + $2;
}
| CLANG_TILDE CLANG_NAME
{
clang_entry.name.clear();
clang_entry.name = $1 + $2;
clang_entry.type = ClangEntry::TypeDtor;
}
;
function_part: /* empty, in this case it means it is a variable */
| '(' {clang_read_signature();} ')' function_suffix
;
function_suffix: /* empty */
| CLANG_DELIM_OPEN {clang_read_type_name(clang_entry.func_suffix);} CLANG_DELIM_CLOSE
;
scope: /* empty */ {$$ = "";}
| CLANG_DELIM_OPEN CLANG_NAME CLANG_CLCL CLANG_DELIM_CLOSE {$$ = $2;}
;
type_name : CLANG_DELIM_OPEN {clang_read_type_name(clang_entry.tmp);} CLANG_DELIM_CLOSE
{
if(clang_entry.tmp.find("enum ") != std::string::npos) {
clang_entry.type = ClangEntry::TypeEnum;
}
}
| CLANG_NAME CLANG_CLCL
{
clang_entry.type = ClangEntry::TypeCtor;
}
| CLANG_NAME
{
clang_entry.type = ClangEntry::TypeClass;
}
;
%%
void clang_parse_string(const std::string& str){
clangEntryVector.clear();
clang_lex_clean();
clang_set_lexer_input(str);
clang_result_parse();
clang_lex_clean();
}
const ClangEntryVector& clang_results() {
return clangEntryVector;
}
void clang_result_error(char*){
}
void clang_read_signature() {
clang_entry.signature = "(";
int depth = 1;
while(depth > 0)
{
int ch = clang_yylex();
if(ch == 0){
break;
}
switch(ch) {
case CLANG_ARG_DELIM_OPEN:
case CLANG_ARG_DELIM_CLOSE:
case CLANG_ARG_OPT_DELIM_OPEN:
case CLANG_ARG_OPT_DELIM_CLOSE:
break;
case (int)'(':
depth++;
break;
case (int)')':
depth--;
if(depth == 0)
clang_yyless(0);
break;
default:
clang_entry.signature += clang_lex_get_string();
clang_entry.signature += " ";
break;
}
}
clang_entry.signature += ")";
}
void clang_read_type_name(std::string &store){
store.clear();
int depth = 1;
while(true)
{
int ch = clang_yylex();
if(ch == 0){
break;
}
switch(ch) {
case CLANG_DELIM_CLOSE:
clang_yyless(0);
return;
default:
store += clang_lex_get_string();
store += " ";
break;
}
}
}
void clang_read_entry_name(std::string &store){
store.clear();
while(true)
{
int ch = clang_yylex();
if(ch == 0){
break;
}
switch(ch) {
case (int)':':
clang_yyless(0);
return;
default:
store += clang_lex_get_string();
store += " ";
break;
}
}
}