~ubuntu-branches/ubuntu/lucid/codelite/lucid

« back to all changes in this revision

Viewing changes to CxxParser/cpp_func_parser.y

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2009-01-12 15:46:55 UTC
  • Revision ID: james.westby@ubuntu.com-20090112154655-sdynrljcb6u167yw
Tags: upstream-1.0.2674+dfsg
ImportĀ upstreamĀ versionĀ 1.0.2674+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%{
 
2
// Copyright Eran Ifrah(c)
 
3
%}
 
4
 
 
5
%{
 
6
/*************** Includes and Defines *****************************/
 
7
#include "string"
 
8
#include "vector"
 
9
#include "stdio.h"
 
10
#include "map"
 
11
#include "function.h"
 
12
 
 
13
#define YYDEBUG_LEXER_TEXT (cl_func_lval)
 
14
#define YYSTYPE std::string
 
15
#define YYDEBUG 0        /* get the pretty debugging code to compile*/
 
16
 
 
17
#ifdef yylex
 
18
#undef yylex
 
19
#define yylex cl_scope_lex
 
20
#endif
 
21
 
 
22
int cl_func_parse();
 
23
void cl_func_error(char *string);
 
24
 
 
25
static FunctionList *g_funcs = NULL;
 
26
static clFunction curr_func;
 
27
 
 
28
//---------------------------------------------
 
29
// externs defined in the lexer
 
30
//---------------------------------------------
 
31
extern char *cl_func_text;
 
32
extern int cl_scope_lex();
 
33
extern bool setLexerInput(const std::string &in, const std::map<std::string, std::string> &ignoreTokens);
 
34
extern int cl_scope_lineno;
 
35
extern void cl_scope_lex_clean();
 
36
 
 
37
 
 
38
/*************** Standard ytab.c continues here *********************/
 
39
%}
 
40
 
 
41
/*************************************************************************/
 
42
 
 
43
/* This group is used by the C/C++ language parser */
 
44
%token  LE_AUTO            LE_DOUBLE          LE_INT             LE_STRUCT
 
45
%token  LE_BREAK           LE_ELSE            LE_LONG            LE_SWITCH
 
46
%token  LE_CASE            LE_ENUM            LE_REGISTER        LE_TYPEDEF
 
47
%token  LE_CHAR            LE_EXTERN          LE_RETURN          LE_UNION
 
48
%token  LE_CONST           LE_FLOAT           LE_SHORT           LE_UNSIGNED
 
49
%token  LE_CONTINUE        LE_FOR             LE_SIGNED          LE_VOID
 
50
%token  LE_DEFAULT         LE_GOTO            LE_SIZEOF          LE_VOLATILE
 
51
%token  LE_DO              LE_IF              LE_STATIC          LE_WHILE
 
52
 
 
53
/* The following are used in C++ only.  ANSI C would call these IDENTIFIERs */
 
54
%token  LE_NEW                  LE_DELETE
 
55
%token  LE_THIS
 
56
%token  LE_OPERATOR
 
57
%token  LE_CLASS
 
58
%token  LE_PUBLIC               LE_PROTECTED       LE_PRIVATE
 
59
%token  LE_VIRTUAL              LE_FRIEND
 
60
%token  LE_INLINE               LE_OVERLOAD
 
61
%token  LE_TEMPLATE                     LE_TYPENAME
 
62
%token  LE_THROW                        LE_CATCH
 
63
 
 
64
/* ANSI C Grammar suggestions */
 
65
%token  LE_IDENTIFIER              LE_STRINGliteral
 
66
%token  LE_FLOATINGconstant        LE_INTEGERconstant        LE_CHARACTERconstant
 
67
%token  LE_OCTALconstant           LE_HEXconstant
 
68
%token  LE_POUNDPOUND LE_CComment LE_CPPComment LE_NAMESPACE LE_USING
 
69
 
 
70
/* New Lexical element, whereas ANSI C suggested non-terminal */
 
71
%token  LE_TYPEDEFname
 
72
 
 
73
/* Multi-Character operators */
 
74
%token   LE_ARROW                                                                                               /*    ->                              */
 
75
%token   LE_ICR LE_DECR                                                                                         /*    ++      --                      */
 
76
%token   LE_LS LE_RS                                                                                            /*    <<      >>                      */
 
77
%token   LE_LE LE_GE LE_EQ LE_NE                                                                /*    <=      >=      ==      !=      */
 
78
%token   LE_ANDAND LE_OROR                                                                                      /*    &&      ||                      */
 
79
%token   LE_ELLIPSIS                                                                                            /*    ...                             */
 
80
                        /* Following are used in C++, not ANSI C        */
 
81
%token   LE_CLCL                                                                                                /*    ::                              */
 
82
%token   LE_DOTstar LE_ARROWstar                                                                                /*    .*       ->*                    */
 
83
 
 
84
/* modifying assignment operators */
 
85
%token  LE_MULTassign  LE_DIVassign    LE_MODassign     /*   *=      /=      %=      */
 
86
%token  LE_PLUSassign  LE_MINUSassign                           /*   +=      -=              */
 
87
%token  LE_LSassign    LE_RSassign                              /*   <<=     >>=             */
 
88
%token  LE_ANDassign   LE_ERassign     LE_ORassign      /*   &=      ^=      |=      */
 
89
%token  LE_MACRO
 
90
%token  LE_DYNAMIC_CAST
 
91
%token  LE_STATIC_CAST
 
92
%token  LE_CONST_CAST
 
93
%token  LE_REINTERPRET_CAST
 
94
 
 
95
%start   translation_unit
 
96
 
 
97
%%
 
98
/* Costants */
 
99
basic_type_name_inter:    LE_INT                        { $$ = $1; }
 
100
                                |       LE_CHAR                 { $$ = $1; }
 
101
                                |       LE_SHORT                { $$ = $1; }
 
102
                                |       LE_LONG                 { $$ = $1; }
 
103
                                |       LE_FLOAT                { $$ = $1; }
 
104
                                |       LE_DOUBLE               { $$ = $1; }
 
105
                                |       LE_SIGNED               { $$ = $1; }
 
106
                                |       LE_UNSIGNED             { $$ = $1; }
 
107
                                |       LE_VOID                 { $$ = $1; }
 
108
                                ;
 
109
 
 
110
basic_type_name:        LE_UNSIGNED basic_type_name_inter       { $$ = $1 + " " + $2; }
 
111
                                |       LE_SIGNED basic_type_name_inter         { $$ = $1 + " " + $2; }
 
112
                                |       LE_LONG LE_LONG                                         { $$ = $1 + " " + $2; }
 
113
                                |       LE_LONG LE_INT                                          { $$ = $1 + " " + $2; }
 
114
                                |       basic_type_name_inter                           { $$ = $1; }
 
115
                                ;
 
116
 
 
117
 
 
118
/* ========================================================================*/
 
119
/* find declarations                                                                                                                               */
 
120
/* ========================================================================*/
 
121
 
 
122
translation_unit        :               /*empty*/
 
123
                                                | translation_unit external_decl
 
124
                                                ;
 
125
 
 
126
external_decl   :               {curr_func.Reset();} function_decl
 
127
                                        |       error {
 
128
                                                        //printf("CodeLite: syntax error, unexpected token '%s' found\n", cl_func_lval.c_str());
 
129
                                                }
 
130
                                        ;
 
131
 
 
132
/*templates*/
 
133
template_arg            :       /* empty */     { $$ = "";}
 
134
                                                | template_specifiter LE_IDENTIFIER {$$ = $1 + " " + $2;}
 
135
                                                ;
 
136
 
 
137
template_arg_list       :       template_arg    { $$ = $1; }
 
138
                                                |       template_arg_list ',' template_arg      { $$ = $1 + " " + $2 + " " + $3; }
 
139
                                                ;
 
140
 
 
141
template_specifiter     :       LE_CLASS        { $$ = $1; }
 
142
                                                        |       LE_TYPENAME     { $$ = $1; }
 
143
                                                        ;
 
144
 
 
145
opt_template_qualifier  : /*empty*/
 
146
                                                        | LE_TEMPLATE '<' template_arg_list '>' { $$ = $1 + $2 + $3 + $4;}
 
147
                                                        ;
 
148
 
 
149
/* the following rules are for template parameters no declarations! */
 
150
template_parameter_list : /* empty */           {$$ = "";}
 
151
                                                        | template_parameter    {$$ = $1;}
 
152
                                                        | template_parameter_list ',' template_parameter {$$ = $1 + $2 + $3;}
 
153
                                                        ;
 
154
 
 
155
template_parameter      :       const_spec nested_scope_specifier LE_IDENTIFIER special_star_amp
 
156
                                                {
 
157
                                                        $$ = $1 +  $2 + $3 +$4;
 
158
                                                }
 
159
                                        |       const_spec nested_scope_specifier basic_type_name special_star_amp
 
160
                                                {
 
161
                                                        $$ = $1 +  $2 + $3 +$4;
 
162
                                                }
 
163
                                        |       const_spec nested_scope_specifier LE_IDENTIFIER '<' template_parameter_list '>' special_star_amp
 
164
                                                {
 
165
                                                        $$ = $1 + $2 + $3 +$4 + $5 + $6 + $7 + " " ;
 
166
                                                }
 
167
                                                ;
 
168
 
 
169
func_name: LE_IDENTIFIER {$$ = $1;}
 
170
                 | '~' LE_IDENTIFIER {$$ = $1 + $2;}
 
171
                 | LE_OPERATOR any_operator {$$ = $1 + $2;}
 
172
                 ;
 
173
 
 
174
any_operator:
 
175
        '+'
 
176
        | '-'
 
177
        | '*'
 
178
        | '/'
 
179
        | '%'
 
180
        | '^'
 
181
        | '&'
 
182
        | '|'
 
183
        | '~'
 
184
        | '!'
 
185
        | '<'
 
186
        | '>'
 
187
        | LE_LS
 
188
        | LE_RS
 
189
        | LE_ANDAND
 
190
        | LE_OROR
 
191
        | LE_ARROW
 
192
        | LE_ARROWstar
 
193
        | '.'
 
194
        | LE_DOTstar
 
195
        | LE_ICR
 
196
        | LE_DECR
 
197
        | LE_LE
 
198
        | LE_GE
 
199
        | LE_EQ
 
200
        | LE_NE
 
201
        | '(' ')'
 
202
        | '[' ']'
 
203
        | LE_NEW
 
204
        | LE_DELETE
 
205
        | ','
 
206
        ;
 
207
 
 
208
/* functions */
 
209
function_decl   :       stmnt_starter opt_template_qualifier virtual_spec const_spec variable_decl nested_scope_specifier func_name '(' {func_consumeFuncArgList();} const_spec declare_throw opt_pure_virtual func_postfix
 
210
                                        {
 
211
                                                //trim down trailing '::' from scope name
 
212
                                                $6.erase($6.find_last_not_of(":")+1);
 
213
                                                curr_func.m_isVirtual = $3.find("virtual") != std::string::npos;
 
214
                                                curr_func.m_isPureVirtual = $12.find("=") != std::string::npos;
 
215
                                                curr_func.m_isConst = $10.find("const") != std::string::npos;
 
216
                                                curr_func.m_name = $7;
 
217
                                                curr_func.m_scope = $6;
 
218
                                                curr_func.m_retrunValusConst = $4;
 
219
                                                curr_func.m_lineno = cl_scope_lineno;
 
220
                                                if(g_funcs)
 
221
                                                {
 
222
                                                        g_funcs->push_back(curr_func);
 
223
                                                }
 
224
                                                curr_func.Reset();
 
225
                                        }
 
226
                                        ;
 
227
 
 
228
declare_throw:  /*empty*/ {$$ = "";}
 
229
                        |       LE_THROW '(' template_parameter_list ')' {$$ = $3;}
 
230
                        ;
 
231
 
 
232
func_postfix: '{'
 
233
                                | ';'
 
234
                                ;
 
235
 
 
236
nested_scope_specifier          : /*empty*/ {$$ = "";}
 
237
                                                        | nested_scope_specifier scope_specifier {      $$ = $1 + $2;}
 
238
                                                        ;
 
239
 
 
240
opt_pure_virtual        : /*empty*/ {$$ = "";}
 
241
                                                | '=' LE_OCTALconstant {$$ = $1 + $2;}
 
242
                                                ;
 
243
 
 
244
scope_specifier :       LE_IDENTIFIER LE_CLCL {$$ = $1+ $2;}
 
245
                                                |       LE_IDENTIFIER  '<' {func_consumeTemplateDecl();} LE_CLCL {$$ = $1 + $4;}
 
246
                                                ;
 
247
 
 
248
virtual_spec            :       /* empty */     {$$ = ""; }
 
249
                                                |       LE_VIRTUAL      { $$ = $1; }
 
250
                                                ;
 
251
 
 
252
const_spec                      :       /* empty */     {$$ = ""; }
 
253
                                                |       LE_CONST        { $$ = $1; }
 
254
                                                ;
 
255
 
 
256
amp_item                                :       /*empty*/       {$$ = ""; }
 
257
                                                |   '&'                         { $$ = $1; }
 
258
                                                ;
 
259
 
 
260
star_list                       :       /*empty*/               {$$ = ""; }
 
261
                                                |       star_list '*'   {$$ = $1 + $2;}
 
262
                                                ;
 
263
 
 
264
special_star_amp                :       star_list amp_item { $$ = $1 + $2; }
 
265
                                                ;
 
266
 
 
267
stmnt_starter           :       /*empty*/ {$$ = "";}
 
268
                                                | ';' { $$ = ";";}
 
269
                                                | ':' { $$ = ":";}      //e.g. private: std::string m_name;
 
270
                                                ;
 
271
 
 
272
/** Variables **/
 
273
variable_decl           :       nested_scope_specifier basic_type_name special_star_amp
 
274
                                                        {
 
275
                                                                $1.erase($1.find_last_not_of(":")+1);
 
276
                                                                curr_func.m_returnValue.m_type = $2;
 
277
                                                                curr_func.m_returnValue.m_typeScope = $1;
 
278
                                                                curr_func.m_returnValue.m_starAmp = $3;
 
279
                                                                curr_func.m_returnValue.m_isPtr = ($3.find("*") != (size_t)-1);
 
280
                                                                $$ = $1 + $2 + $3;
 
281
                                                        }
 
282
                                                |       nested_scope_specifier LE_IDENTIFIER special_star_amp
 
283
                                                        {
 
284
                                                                $1.erase($1.find_last_not_of(":")+1);
 
285
                                                                curr_func.m_returnValue.m_type = $2;
 
286
                                                                curr_func.m_returnValue.m_typeScope = $1;
 
287
                                                                curr_func.m_returnValue.m_starAmp = $3;
 
288
                                                                curr_func.m_returnValue.m_isPtr = ($3.find("*") != (size_t)-1);
 
289
                                                                $$ = $1 + $2 + $3  ;
 
290
                                                        }
 
291
                                                |       nested_scope_specifier LE_IDENTIFIER '<' template_parameter_list '>' special_star_amp
 
292
                                                        {
 
293
                                                                $1.erase($1.find_last_not_of(":")+1);
 
294
                                                                curr_func.m_returnValue.m_type = $2;
 
295
                                                                curr_func.m_returnValue.m_typeScope = $1;
 
296
                                                                curr_func.m_returnValue.m_starAmp = $6;
 
297
                                                                curr_func.m_returnValue.m_isPtr = ($6.find("*") != (size_t)-1);
 
298
                                                                curr_func.m_returnValue.m_isTemplate = true;
 
299
                                                                curr_func.m_returnValue.m_templateDecl = $4;
 
300
                                                                $$ = $1 + $2 + $3  + $4 + $5 + $6 ;
 
301
                                                        }
 
302
                                                ;
 
303
%%
 
304
void yyerror(char *s) {}
 
305
 
 
306
void func_consumeFuncArgList()
 
307
{
 
308
        curr_func.m_signature = "(";
 
309
 
 
310
        int depth = 1;
 
311
        while(depth > 0)
 
312
        {
 
313
                int ch = cl_scope_lex();
 
314
                if(ch == 0)
 
315
                {
 
316
                        break;
 
317
                }
 
318
 
 
319
                curr_func.m_signature += cl_func_lval;
 
320
                curr_func.m_signature += " ";
 
321
                if(ch == ')')
 
322
                {
 
323
                        depth--;
 
324
                        continue;
 
325
                }
 
326
                else if(ch == '(')
 
327
                {
 
328
                        depth ++ ;
 
329
                        continue;
 
330
                }
 
331
        }
 
332
}
 
333
 
 
334
/**
 
335
 * consume all token until matching closing brace is found
 
336
 */
 
337
void func_consumeDecl()
 
338
{
 
339
        int depth = 1;
 
340
        while(depth > 0)
 
341
        {
 
342
                int ch = cl_scope_lex();
 
343
                //printf("ch=%d\n", ch);
 
344
                //fflush(stdout);
 
345
                if(ch ==0)
 
346
                {
 
347
                        break;
 
348
                }
 
349
                if(ch == '}')
 
350
                {
 
351
                        depth--;
 
352
                        continue;
 
353
                }
 
354
                else if(ch == '{')
 
355
                {
 
356
                        depth ++ ;
 
357
                        continue;
 
358
                }
 
359
        }
 
360
 
 
361
}
 
362
 
 
363
void func_consumeTemplateDecl()
 
364
{
 
365
        int depth = 1;
 
366
        while(depth > 0)
 
367
        {
 
368
                int ch = cl_scope_lex();
 
369
                //printf("ch=%d\n", ch);
 
370
                //fflush(stdout);
 
371
                if(ch ==0){
 
372
                        break;
 
373
                }
 
374
 
 
375
                if(ch == '>')
 
376
                {
 
377
                        depth--;
 
378
                        continue;
 
379
                }
 
380
                else if(ch == '<')
 
381
                {
 
382
                        depth ++ ;
 
383
                        continue;
 
384
                }
 
385
        }
 
386
}
 
387
 
 
388
// return the scope name at the end of the input string
 
389
void get_functions(const std::string &in, FunctionList &li, const std::map<std::string, std::string> &ignoreTokens)
 
390
{
 
391
        if( !setLexerInput(in, ignoreTokens) )
 
392
        {
 
393
                return;
 
394
        }
 
395
 
 
396
        g_funcs = &li;
 
397
 
 
398
        //call tghe main parsing routine
 
399
        cl_func_parse();
 
400
        g_funcs = NULL;
 
401
 
 
402
        //do the lexer cleanup
 
403
        cl_scope_lex_clean();
 
404
}