1 /******************************************************************************
5 * Copyright (C) 1997-2015 by Dimitri van Heesch.
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.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
17 %option never-interactive
18 %option prefix="declinfoYY"
22 %option extra-type="struct declinfoYY_state *"
25 // forward declare yyscan_t to improve type safety
26 #define YY_TYPEDEF_YY_SCANNER_T
28 typedef yyguts_t *yyscan_t;
37 //#include <iostream.h>
47 #define YY_NO_UNISTD_H 1
48 #define YY_NEVER_INTERACTIVE 1
50 #define USE_STATE2STRING 0
52 /* -----------------------------------------------------------------
56 struct declinfoYY_state
58 const char *inputString;
62 QCString classTempList;
63 QCString funcTempList;
69 bool classTempListFound;
70 bool funcTempListFound;
71 QCString exceptionString;
77 static const char *stateToString(int state);
80 static void addType(yyscan_t yyscanner);
81 static void addTypeName(yyscan_t yyscanner);
82 static yy_size_t yyread(char *buf,yy_size_t max_size, yyscan_t yyscanner);
84 /* -----------------------------------------------------------------
87 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size,yyscanner);
92 ID ([$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+)
103 <Start>"operator"/({B}*"["{B}*"]")* { // operator rule must be before {ID} rule
104 yyextra->name += yytext;
107 <Start>{ID}{B}*"("{B}*{ID}{B}*")" { // Objective-C class categories
108 if (!yyextra->insideObjC)
114 yyextra->name += yytext;
117 <Start>([~!]{B}*)?{ID}{B}*"["{B}*"]" { // PHP
118 if (!yyextra->insidePHP)
122 addTypeName(yyscanner);
123 yyextra->name += removeRedundantWhiteSpace(QCString(yytext));
125 <Start>([~!]{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java,
126 // the / was add to deal with multi-
127 // dimensional C++ arrays like A[][15]
128 // the leading ~ is for a destructor
129 // the leading ! is for a C++/CLI finalizer (see bug 456475 and 635198)
130 addTypeName(yyscanner);
131 yyextra->name += removeRedundantWhiteSpace(QCString(yytext));
133 <Start>{B}*"::"{B}* { // found a yyextra->scope specifier
134 if (!yyextra->scope.isEmpty())
136 yyextra->scope+="::"+yyextra->name; // add yyextra->name to yyextra->scope
140 yyextra->scope = yyextra->name; // yyextra->scope becomes yyextra->name
142 yyextra->name.resize(0);
144 <Start>{B}*":" { // Objective-C argument separator
145 yyextra->name+=yytext;
149 yyextra->type+=yytext;
154 <Start>{B}*"("({ID}"::")*{B}*[&*]({B}*("const"|"volatile"){B}+)? {
155 if (yyextra->insidePHP) REJECT;
157 QCString text(yytext);
158 yyextra->type+=text.stripWhiteSpace();
163 <Start>{B}*"decltype"/{B}*"(" {
164 yyextra->roundCount=0;
165 yyextra->type="decltype";
169 ++yyextra->roundCount;
174 if (--yyextra->roundCount == 0) {
179 yyextra->type+=yytext;
181 <Start>{B}*"(" { // TODO: function pointers
191 yyextra->sharpCount=0;
192 yyextra->roundCount=0;
195 <Template>"<<" { yyextra->name+="<<"; }
196 <Template>">>" { yyextra->name+=">>"; }
197 <Template>"(" { yyextra->name+="(";
198 yyextra->roundCount++;
200 <Template>")" { yyextra->name+=")";
201 if (yyextra->roundCount>0)
203 yyextra->roundCount--;
208 if (yyextra->roundCount==0)
210 yyextra->sharpCount++;
215 if (yyextra->roundCount==0)
217 if (yyextra->sharpCount)
218 --yyextra->sharpCount;
226 yyextra->name+=*yytext;
228 <Operator>{B}*"("{B}*")"{B}*"<>"{Bopt}/"(" {
229 yyextra->name+="() <>";
232 <Operator>{B}*"("{B}*")"{Bopt}/"(" {
236 <Operator>[^(]*{B}*("<>"{B}*)?/"(" {
237 yyextra->name+=yytext;
240 <ReadArgs>"throw"{B}*"(" {
241 yyextra->exceptionString="throw(";
242 BEGIN(ReadExceptions);
245 yyextra->args+=*yytext;
248 yyextra->exceptionString+=*yytext;
255 static void addType(yyscan_t yyscanner)
257 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
258 //printf("addType() yyextra->type='%s' yyextra->scope='%s' yyextra->name='%s'\n",
259 // qPrint(yyextra->type),qPrint(yyextra->scope),qPrint(yyextra->name));
260 if (yyextra->name.isEmpty() && yyextra->scope.isEmpty()) return;
261 if (!yyextra->type.isEmpty()) yyextra->type+=" ";
262 if (!yyextra->scope.isEmpty()) yyextra->type+=yyextra->scope+"::";
263 yyextra->type+=yyextra->name;
264 yyextra->scope.resize(0);
265 yyextra->name.resize(0);
268 static void addTypeName(yyscan_t yyscanner)
270 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
271 //printf("addTypeName() yyextra->type='%s' yyextra->scope='%s' yyextra->name='%s'\n",
272 // qPrint(yyextra->type),qPrint(yyextra->scope),qPrint(yyextra->name));
273 if (yyextra->name.isEmpty() ||
274 yyextra->name.at(yyextra->name.length()-1)==':') // end of Objective-C keyword => append to yyextra->name not yyextra->type
278 if (!yyextra->type.isEmpty()) yyextra->type+=' ';
279 yyextra->type+=yyextra->name;
280 yyextra->name.resize(0);
283 static yy_size_t yyread(char *buf,yy_size_t max_size, yyscan_t yyscanner)
285 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
287 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
289 *buf = yyextra->inputString[yyextra->inputPosition++] ;
295 /*@ public interface------------------------------------------------------------
297 static yyscan_t g_yyscanner;
298 static struct declinfoYY_state g_declinfo_extra;
300 void parseFuncDecl(const QCString &decl,const SrcLangExt lang,QCString &cl,QCString &t,
301 QCString &n,QCString &a,QCString &ftl,QCString &exc)
307 declinfoYYlex_init_extra(&g_declinfo_extra, &g_yyscanner);
308 struct yyguts_t *yyg = (struct yyguts_t*)g_yyscanner;
311 declinfoYYset_debug(1,g_yyscanner);
314 printlex(yy_flex_debug, TRUE, __FILE__, NULL);
315 yyextra->inputString = decl.data();
316 //printf("Input='%s'\n",yyextra->inputString);
317 yyextra->inputPosition = 0;
318 yyextra->classTempListFound = FALSE;
319 yyextra->funcTempListFound = FALSE;
320 yyextra->insideObjC = lang==SrcLangExt_ObjC;
321 yyextra->insidePHP = lang==SrcLangExt_PHP;
322 yyextra->scope.resize(0);
323 yyextra->className.resize(0);
324 yyextra->classTempList.resize(0);
325 yyextra->funcTempList.resize(0);
326 yyextra->name.resize(0);
327 yyextra->type.resize(0);
328 yyextra->args.resize(0);
329 yyextra->exceptionString.resize(0);
330 // first we try to find the yyextra->type, yyextra->scope, yyextra->name and arguments
331 declinfoYYrestart( yyin, g_yyscanner );
333 declinfoYYlex(g_yyscanner);
335 //printf("yyextra->type='%s' class='%s' yyextra->name='%s' yyextra->args='%s'\n",
336 // qPrint(yyextra->type),qPrint(yyextra->scope),qPrint(yyextra->name),qPrint(yyextra->args));
338 int nb = yyextra->name.findRev('[');
339 if (nb!=-1 && yyextra->args.isEmpty()) // correct for [] in yyextra->name ambiguity (due to Java return yyextra->type allowing [])
341 yyextra->args.prepend(yyextra->name.right(yyextra->name.length()-nb));
342 yyextra->name=yyextra->name.left(nb);
347 int l=yyextra->scope.length();
354 char c=yyextra->scope.at(i);
359 else if (skipCount==0)
363 cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(yyextra->scope),FALSE);
368 n=removeRedundantWhiteSpace(yyextra->name);
370 if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1)
371 // TODO: handle cases like where n="operator<< <T>"
373 ftl=removeRedundantWhiteSpace(n.right(n.length()-il));
377 //ctl=yyextra->classTempList.copy();
378 //ftl=yyextra->funcTempList.copy();
379 t=removeRedundantWhiteSpace(yyextra->type);
380 a=removeRedundantWhiteSpace(yyextra->args);
381 exc=removeRedundantWhiteSpace(yyextra->exceptionString);
383 if (!t.isEmpty() && !t.startsWith("decltype") && t.at(t.length()-1)==')') // for function pointers
386 t=t.left(t.length()-1);
388 //printf("yyextra->type='%s' class='%s' yyextra->name='%s' yyextra->args='%s'\n",
389 // qPrint(t),qPrint(cl),qPrint(n),qPrint(a));
391 printlex(yy_flex_debug, FALSE, __FILE__, NULL);
392 declinfoYYlex_destroy(g_yyscanner);
397 void dumpDecl(const char *s)
399 QCString yyextra->className;
400 QCString classTNames;
401 QCString yyextra->type;
402 QCString yyextra->name;
403 QCString yyextra->args;
405 msg("-----------------------------------------\n");
406 parseFuncDecl(s,yyextra->className,classTNames,yyextra->type,yyextra->name,yyextra->args,funcTNames);
407 msg("yyextra->type='%s' class='%s' classTempl='%s' yyextra->name='%s' "
408 "funcTemplateNames='%s' yyextra->args='%s'\n",
409 qPrint(yyextra->type),qPrint(yyextra->className),qPrint(classTNames),
410 qPrint(yyextra->name),qPrint(funcTNames),qPrint(yyextra->args)
417 dumpDecl("A < T > :: Value * A < T > :: getValue < S > ( const A < T > & a )");
418 dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)");
420 dumpDecl("friend void bla<>()");
421 dumpDecl("yyextra->name< T > :: operator () (int bla)");
422 dumpDecl("yyextra->name< T > :: operator << (int bla)");
423 dumpDecl("yyextra->name< T > :: operator << <> (int bla)");
424 dumpDecl("yyextra->className::func()");
425 dumpDecl("void ( * yyextra->Name < T > :: bla ) ( int, char * )");
430 #include "declinfo.l.h"