2
// Copyright Eran Ifrah(c)
6
/*************** Includes and Defines *****************************/
13
#define YYDEBUG_LEXER_TEXT (cl_func_lval)
14
#define YYSTYPE std::string
15
#define YYDEBUG 0 /* get the pretty debugging code to compile*/
19
#define yylex cl_scope_lex
23
void cl_func_error(char *string);
25
static FunctionList *g_funcs = NULL;
26
static clFunction curr_func;
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();
38
/*************** Standard ytab.c continues here *********************/
41
/*************************************************************************/
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
53
/* The following are used in C++ only. ANSI C would call these IDENTIFIERs */
54
%token LE_NEW LE_DELETE
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
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
70
/* New Lexical element, whereas ANSI C suggested non-terminal */
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 /* .* ->* */
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 /* &= ^= |= */
90
%token LE_DYNAMIC_CAST
93
%token LE_REINTERPRET_CAST
95
%start translation_unit
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; }
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; }
118
/* ========================================================================*/
119
/* find declarations */
120
/* ========================================================================*/
122
translation_unit : /*empty*/
123
| translation_unit external_decl
126
external_decl : {curr_func.Reset();} function_decl
128
//printf("CodeLite: syntax error, unexpected token '%s' found\n", cl_func_lval.c_str());
133
template_arg : /* empty */ { $$ = "";}
134
| template_specifiter LE_IDENTIFIER {$$ = $1 + " " + $2;}
137
template_arg_list : template_arg { $$ = $1; }
138
| template_arg_list ',' template_arg { $$ = $1 + " " + $2 + " " + $3; }
141
template_specifiter : LE_CLASS { $$ = $1; }
142
| LE_TYPENAME { $$ = $1; }
145
opt_template_qualifier : /*empty*/
146
| LE_TEMPLATE '<' template_arg_list '>' { $$ = $1 + $2 + $3 + $4;}
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;}
155
template_parameter : const_spec nested_scope_specifier LE_IDENTIFIER special_star_amp
157
$$ = $1 + $2 + $3 +$4;
159
| const_spec nested_scope_specifier basic_type_name special_star_amp
161
$$ = $1 + $2 + $3 +$4;
163
| const_spec nested_scope_specifier LE_IDENTIFIER '<' template_parameter_list '>' special_star_amp
165
$$ = $1 + $2 + $3 +$4 + $5 + $6 + $7 + " " ;
169
func_name: LE_IDENTIFIER {$$ = $1;}
170
| '~' LE_IDENTIFIER {$$ = $1 + $2;}
171
| LE_OPERATOR any_operator {$$ = $1 + $2;}
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
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;
222
g_funcs->push_back(curr_func);
228
declare_throw: /*empty*/ {$$ = "";}
229
| LE_THROW '(' template_parameter_list ')' {$$ = $3;}
236
nested_scope_specifier : /*empty*/ {$$ = "";}
237
| nested_scope_specifier scope_specifier { $$ = $1 + $2;}
240
opt_pure_virtual : /*empty*/ {$$ = "";}
241
| '=' LE_OCTALconstant {$$ = $1 + $2;}
244
scope_specifier : LE_IDENTIFIER LE_CLCL {$$ = $1+ $2;}
245
| LE_IDENTIFIER '<' {func_consumeTemplateDecl();} LE_CLCL {$$ = $1 + $4;}
248
virtual_spec : /* empty */ {$$ = ""; }
249
| LE_VIRTUAL { $$ = $1; }
252
const_spec : /* empty */ {$$ = ""; }
253
| LE_CONST { $$ = $1; }
256
amp_item : /*empty*/ {$$ = ""; }
260
star_list : /*empty*/ {$$ = ""; }
261
| star_list '*' {$$ = $1 + $2;}
264
special_star_amp : star_list amp_item { $$ = $1 + $2; }
267
stmnt_starter : /*empty*/ {$$ = "";}
269
| ':' { $$ = ":";} //e.g. private: std::string m_name;
273
variable_decl : nested_scope_specifier basic_type_name special_star_amp
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);
282
| nested_scope_specifier LE_IDENTIFIER special_star_amp
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);
291
| nested_scope_specifier LE_IDENTIFIER '<' template_parameter_list '>' special_star_amp
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 ;
304
void yyerror(char *s) {}
306
void func_consumeFuncArgList()
308
curr_func.m_signature = "(";
313
int ch = cl_scope_lex();
319
curr_func.m_signature += cl_func_lval;
320
curr_func.m_signature += " ";
335
* consume all token until matching closing brace is found
337
void func_consumeDecl()
342
int ch = cl_scope_lex();
343
//printf("ch=%d\n", ch);
363
void func_consumeTemplateDecl()
368
int ch = cl_scope_lex();
369
//printf("ch=%d\n", ch);
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)
391
if( !setLexerInput(in, ignoreTokens) )
398
//call tghe main parsing routine
402
//do the lexer cleanup
403
cl_scope_lex_clean();