Doxygen
Loading...
Searching...
No Matches
declinfo.l
Go to the documentation of this file.
1/******************************************************************************
2 *
3 *
4 *
5 * Copyright (C) 1997-2015 by Dimitri van Heesch.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
12 *
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
15 *
16 */
17%option never-interactive
18%option prefix="declinfoYY"
19%option nounput
20%option noyywrap
21%option reentrant
22%option extra-type="struct declinfoYY_state *"
23%top{
24#include <stdint.h>
25// forward declare yyscan_t to improve type safety
26#define YY_TYPEDEF_YY_SCANNER_T
27struct yyguts_t;
28typedef yyguts_t *yyscan_t;
yyguts_t * yyscan_t
Definition code.l:24
29}
30
31%{
32
33/*
34 * includes
35 */
36#include <stdio.h>
37//#include <iostream.h>
38#include <assert.h>
39#include <ctype.h>
40
41#include "declinfo.h"
42#include "util.h"
43#include "message.h"
44#include "types.h"
45#include "debug.h"
46
47#define YY_NO_INPUT 1
48#define YY_NO_UNISTD_H 1
49#define YY_NEVER_INTERACTIVE 1
50
51/* -----------------------------------------------------------------
52 *
53 * statics
54 */
75
76[[maybe_unused]] static const char *stateToString(int state);
77
78static void addType(yyscan_t yyscanner);
79static void addTypeName(yyscan_t yyscanner);
80static int yyread(char *buf,int max_size, yyscan_t yyscanner);
81
82/* -----------------------------------------------------------------
83 */
84#undef YY_INPUT
85#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner);
86
87// otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
88static inline const char *getLexerFILE() {return __FILE__;}
89#define LEX_NO_INPUT_FILENAME
90#include "doxygen_lex.h"
This is an alternative implementation of QCString.
Definition qcstring.h:101
static int yyread(char *buf, int max_size, yyscan_t yyscanner)
Definition declinfo.l:308
static void addTypeName(yyscan_t yyscanner)
Definition declinfo.l:293
static const char * stateToString(int state)
static const char * getLexerFILE()
Definition declinfo.l:88
static void addType(yyscan_t yyscanner)
Definition declinfo.l:280
QCString type
Definition declinfo.l:63
const char * inputString
Definition declinfo.l:57
QCString name
Definition declinfo.l:64
bool funcTempListFound
Definition declinfo.l:69
QCString funcTempList
Definition declinfo.l:62
QCString exceptionString
Definition declinfo.l:70
bool classTempListFound
Definition declinfo.l:68
QCString className
Definition declinfo.l:60
QCString scope
Definition declinfo.l:59
QCString args
Definition declinfo.l:65
QCString classTempList
Definition declinfo.l:61
This file contains a number of basic enums and types.
A bunch of utility functions.
91%}
92
93B [ \t]
94Bopt {B}*
95ID ([$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+)
96
97%x Start
98%x Template
99%x ReadArgs
100%x Operator
101%x DeclType
102%x ReadExceptions
103
105
106<Start>"operator"/({B}*"["{B}*"]")* { // operator rule must be before {ID} rule
107 yyextra->name += yytext;
108 BEGIN(Operator);
109 }
110<Start>{ID}({B}*"*")?{B}*"("{B}*"^"{B}*")"{B}*"(" { // Objective-C 2.0 block return type
111 if (!yyextra->insideObjC)
112 {
113 REJECT;
114 }
115 else
116 {
117 addType(yyscanner);
118 yyextra->type += yytext;
119 }
120 }
static void addType(yyscan_t yyscanner)
Definition code.l:2603
121<Start>{ID}{B}*"("{B}*{ID}{B}*")" { // Objective-C class categories
122 if (!yyextra->insideObjC)
123 {
124 REJECT;
125 }
126 else
127 {
128 yyextra->name += yytext;
129 }
130 }
131<Start>([~!]{B}*)?{ID}{B}*"["{B}*"]" { // PHP
132 if (!yyextra->insidePHP)
133 {
134 REJECT;
135 }
136 addTypeName(yyscanner);
137 yyextra->name += removeRedundantWhiteSpace(QCString(yytext));
138 }
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578
139<Start>"anonymous_namespace{"[^}]+"}" { // anonymous namespace
140 if (!yyextra->scope.isEmpty())
141 {
142 yyextra->scope+=QCString("::")+yytext;
143 }
144 else
145 {
146 yyextra->scope = yytext;
147 }
148 }
149<Start>([~!]{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java,
150 // the / was add to deal with multi-
151 // dimensional C++ arrays like A[][15]
152 // the leading ~ is for a destructor
153 // the leading ! is for a C++/CLI finalizer (see bug 456475 and 635198)
154 addTypeName(yyscanner);
155 yyextra->name += removeRedundantWhiteSpace(QCString(yytext));
156 }
157<Start>{B}*"::"{B}* { // found a yyextra->scope specifier
158 if (!yyextra->scope.isEmpty() && !yyextra->scope.endsWith("::"))
159 {
160 if (!yyextra->name.isEmpty()) yyextra->scope+="::"+yyextra->name; // add yyextra->name to yyextra->scope
161 }
162 else
163 {
164 yyextra->scope = yyextra->name; // yyextra->scope becomes yyextra->name
165 }
166 yyextra->name.clear();
167 }
168<Start>{B}*":" { // Objective-C argument separator
169 yyextra->name+=yytext;
170 }
171<Start>[*&]+ {
172 addType(yyscanner);
173 yyextra->type+=yytext;
174 }
175<Start>{B}+ {
176 addType(yyscanner);
177 }
178<Start>{B}*"("({ID}"::")*{B}*[&*]({B}*("const"|"volatile"){B}+)? {
179 if (yyextra->insidePHP) REJECT;
180 if (yyextra->insidePython) REJECT;
181 addType(yyscanner);
182 QCString text(yytext);
183 yyextra->type+=text.stripWhiteSpace();
184 }
185<Start>{B}*")" {
186 yyextra->type+=")";
187 }
188<Start>{B}*"decltype"/{B}*"(" {
189 yyextra->roundCount=0;
190 yyextra->type="decltype";
191 BEGIN(DeclType);
192 }
193<DeclType>{B}*"(" {
194 ++yyextra->roundCount;
195 yyextra->type+="(";
196 }
197<DeclType>{B}*")" {
198 yyextra->type+=")";
199 if (--yyextra->roundCount == 0) {
200 BEGIN(Start);
201 }
202 }
203<DeclType>. {
204 yyextra->type+=yytext;
205 }
206<Start>{B}*"(" { // TODO: function pointers
207 yyextra->args+="(";
208 BEGIN(ReadArgs);
209 }
210<Start>{B}*"[" {
211 yyextra->args+="[";
212 BEGIN(ReadArgs);
213 }
214<Start>{B}*"<" {
215 yyextra->name+="<";
216 yyextra->sharpCount=0;
217 yyextra->roundCount=0;
218 BEGIN(Template);
219 }
220<Template>"<<" { yyextra->name+="<<"; }
221<Template>">>" { yyextra->name+=">>"; }
222<Template>"(" { yyextra->name+="(";
223 yyextra->roundCount++;
224 }
225<Template>")" { yyextra->name+=")";
226 if (yyextra->roundCount>0)
227 {
228 yyextra->roundCount--;
229 }
230 }
231<Template>"<" {
232 yyextra->name+="<";
233 if (yyextra->roundCount==0)
234 {
235 yyextra->sharpCount++;
236 }
237 }
238<Template>">" {
239 yyextra->name+=">";
240 if (yyextra->roundCount==0)
241 {
242 if (yyextra->sharpCount)
243 --yyextra->sharpCount;
244 else
245 {
246 BEGIN(Start);
247 }
248 }
249 }
250<Template>. {
251 yyextra->name+=*yytext;
252 }
253<Operator>{B}*"("{B}*")"{B}*"<>"{Bopt}/"(" {
254 yyextra->name+="() <>";
255 BEGIN(ReadArgs);
256 }
257<Operator>{B}*"("{B}*")"{Bopt}/"(" {
258 yyextra->name+="()";
259 BEGIN(ReadArgs);
260 }
261<Operator>[^(]*{B}*("<>"{B}*)?/"(" {
262 yyextra->name+=yytext;
263 BEGIN(ReadArgs);
264 }
265<ReadArgs>"throw"{B}*"(" {
266 yyextra->exceptionString="throw(";
267 BEGIN(ReadExceptions);
268 }
269<ReadArgs>. {
270 yyextra->args+=*yytext;
271 }
272<ReadExceptions>. {
273 yyextra->exceptionString+=*yytext;
274 }
275<*>.
276<*>\n
277
278%%
279
280static void addType(yyscan_t yyscanner)
281{
282 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
283 //printf("addType() yyextra->type='%s' yyextra->scope='%s' yyextra->name='%s'\n",
284 // qPrint(yyextra->type),qPrint(yyextra->scope),qPrint(yyextra->name));
285 if (yyextra->name.isEmpty() && yyextra->scope.isEmpty()) return;
286 if (!yyextra->type.isEmpty()) yyextra->type+=" ";
287 if (!yyextra->scope.isEmpty()) yyextra->type+=yyextra->scope+"::";
288 yyextra->type+=yyextra->name;
289 yyextra->scope.clear();
290 yyextra->name.clear();
291}
292
293static void addTypeName(yyscan_t yyscanner)
294{
295 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
296 //printf("addTypeName() yyextra->type='%s' yyextra->scope='%s' yyextra->name='%s'\n",
297 // qPrint(yyextra->type),qPrint(yyextra->scope),qPrint(yyextra->name));
298 if (yyextra->name.isEmpty() ||
299 yyextra->name.at(yyextra->name.length()-1)==':') // end of Objective-C keyword => append to yyextra->name not yyextra->type
300 {
301 return;
302 }
303 if (!yyextra->type.isEmpty()) yyextra->type+=' ';
304 yyextra->type+=yyextra->name;
305 yyextra->name.clear();
306}
307
308static int yyread(char *buf,int max_size, yyscan_t yyscanner)
309{
310 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
311 int c=0;
312 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
313 {
314 *buf = yyextra->inputString[yyextra->inputPosition++] ;
315 c++; buf++;
316 }
317 return c;
318}
319
320/*@ public interface------------------------------------------------------------
321 */
324
325void parseFuncDecl(const QCString &decl,const SrcLangExt lang,QCString &cl,QCString &t,
326 QCString &n,QCString &a,QCString &ftl,QCString &exc)
327{
328 if (decl.isEmpty())
329 {
330 return;
331 }
332 declinfoYYlex_init_extra(&g_declinfo_extra, &g_yyscanner);
333 struct yyguts_t *yyg = (struct yyguts_t*)g_yyscanner;
334
335#ifdef FLEX_DEBUG
336 declinfoYYset_debug(Debug::isFlagSet(Debug::Lex_declinfo)?1:0,g_yyscanner);
337#endif
338
339 DebugLex debugLex(Debug::Lex_declinfo,__FILE__, NULL);
340 yyextra->inputString = decl.data();
341 //printf("Input='%s'\n",yyextra->inputString);
342 yyextra->inputPosition = 0;
343 yyextra->classTempListFound = FALSE;
344 yyextra->funcTempListFound = FALSE;
345 yyextra->insideObjC = lang==SrcLangExt::ObjC;
346 yyextra->insidePHP = lang==SrcLangExt::PHP;
347 yyextra->insidePython = lang==SrcLangExt::Python;
348 yyextra->scope.clear();
349 yyextra->className.clear();
350 yyextra->classTempList.clear();
351 yyextra->funcTempList.clear();
352 yyextra->name.clear();
353 yyextra->type.clear();
354 yyextra->args.clear();
355 yyextra->exceptionString.clear();
356 // first we try to find the yyextra->type, yyextra->scope, yyextra->name and arguments
357 declinfoYYrestart( yyin, g_yyscanner );
358 BEGIN( Start );
359 declinfoYYlex(g_yyscanner);
360
361 //printf("yyextra->type='%s' class='%s' yyextra->name='%s' yyextra->args='%s'\n",
362 // qPrint(yyextra->type),qPrint(yyextra->scope),qPrint(yyextra->name),qPrint(yyextra->args));
363
364 int nb = yyextra->name.findRev('[');
365 if (nb!=-1 && yyextra->args.isEmpty()) // correct for [] in yyextra->name ambiguity (due to Java return yyextra->type allowing [])
366 {
367 yyextra->args.prepend(yyextra->name.right(yyextra->name.length()-nb));
368 yyextra->name=yyextra->name.left(nb);
369 }
370
371 cl=yyextra->scope;
372 n=removeRedundantWhiteSpace(yyextra->name);
373 int il=n.find('<'), ir=n.findRev('>');
374 if (il!=-1 && ir!=-1 && n.at(il+1)!='=')
375 // prevent <=>
376 // TODO: handle cases like where n="operator<< <T>"
377 {
379 n=n.left(il);
380 }
381
382 //ctl=yyextra->classTempList.copy();
383 //ftl=yyextra->funcTempList.copy();
384 t=removeRedundantWhiteSpace(yyextra->type);
385 a=removeRedundantWhiteSpace(yyextra->args);
386 exc=removeRedundantWhiteSpace(yyextra->exceptionString);
387
388 if (!t.isEmpty() && !t.startsWith("decltype") && t.at(t.length()-1)==')') // for function pointers
389 {
390 a.prepend(")");
391 t=t.left(t.length()-1);
392 }
393 //printf("yyextra->type='%s' class='%s' yyextra->name='%s' yyextra->args='%s'\n",
394 // qPrint(t),qPrint(cl),qPrint(n),qPrint(a));
395
396 declinfoYYlex_destroy(g_yyscanner);
397 return;
398}
399
400#if 0
401void dumpDecl(const char *s)
402{
403 QCString yyextra->className;
404 QCString classTNames;
405 QCString yyextra->type;
406 QCString yyextra->name;
407 QCString yyextra->args;
408 QCString funcTNames;
409 msg("-----------------------------------------\n");
410 parseFuncDecl(s,yyextra->className,classTNames,yyextra->type,yyextra->name,yyextra->args,funcTNames);
411 msg("yyextra->type='%s' class='%s' classTempl='%s' yyextra->name='%s' "
412 "funcTemplateNames='%s' yyextra->args='%s'\n",
413 qPrint(yyextra->type),qPrint(yyextra->className),qPrint(classTNames),
414 qPrint(yyextra->name),qPrint(funcTNames),qPrint(yyextra->args)
415 );
416}
417
418// some test code
419int main()
420{
421 dumpDecl("A < T > :: Value * A < T > :: getValue < S > ( const A < T > & a )");
422 dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)");
423 dumpDecl("func()");
424 dumpDecl("friend void bla<>()");
425 dumpDecl("yyextra->name< T > :: operator () (int bla)");
426 dumpDecl("yyextra->name< T > :: operator << (int bla)");
427 dumpDecl("yyextra->name< T > :: operator << <> (int bla)");
428 dumpDecl("yyextra->className::func()");
429 dumpDecl("void ( * yyextra->Name < T > :: bla ) ( int, char * )");
430}
431#endif
432
433#include "declinfo.l.h"
@ Lex_declinfo
Definition debug.h:56
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:135
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:407
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool startsWith(const char *s) const
Definition qcstring.h:492
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
QCString right(size_t len) const
Definition qcstring.h:219
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
QCString left(size_t len) const
Definition qcstring.h:214
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3980
void parseFuncDecl(const QCString &decl, const SrcLangExt lang, QCString &clName, QCString &type, QCString &name, QCString &args, QCString &funcTempList, QCString &exceptions)
Definition declinfo.l:325
static yyscan_t g_yyscanner
Definition declinfo.l:322
static struct declinfoYY_state g_declinfo_extra
Definition declinfo.l:323
int main(int argc, char **argv)
Definition main.cpp:31
void msg(const char *fmt,...)
Definition message.cpp:98
const char * qPrint(const char *s)
Definition qcstring.h:672
#define FALSE
Definition qcstring.h:34
SrcLangExt
Language as given by extension.
Definition types.h:42
@ Python
Definition types.h:52