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