Doxygen
Loading...
Searching...
No Matches
lexscanner.l
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 1997-2021 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="lexscannerYY"
17%option reentrant
18%option extra-type="struct lexscannerYY_state *"
19%option noyywrap
20
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/*
32 * includes
33 */
34
35#include <algorithm>
36#include <vector>
37#include <utility>
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <assert.h>
42#include <ctype.h>
43
44#include "config.h"
45#include "lexscanner.h"
46#include "entry.h"
47#include "message.h"
48#include "util.h"
49#include "scanner.h"
50#include "debug.h"
51
52#define YY_NO_INPUT 1
53#define YY_NO_UNISTD_H 1
54
55#define repeatChar(chr, cnt) std::string(cnt, chr).c_str()
56
91
92[[maybe_unused]] static const char *stateToString(int state);
93//-----------------------------------------------------------------------------
94
95// forward declarations for statefull functions
96static void handleCCode(yyscan_t yyscanner);
97static int yyread(yyscan_t yyscanner,char *buf,int max_size);
98
99/* ----------------------------------------------------------------- */
100#undef YY_INPUT
101#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
102
103// otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
104static inline const char *getLexerFILE() {return __FILE__;}
105#include "doxygen_lex.h"
106
C-like language parser using state-based lexical scanning.
Definition scanner.h:30
Clang parser object for a single translation unit, which consists of a source file and the directly o...
Definition clangparser.h:25
This is an alternative implementation of QCString.
Definition qcstring.h:101
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition lexscanner.l:929
static const char * stateToString(int state)
static void handleCCode(yyscan_t yyscanner)
Definition lexscanner.l:983
static const char * getLexerFILE()
Definition lexscanner.l:104
#define FALSE
Definition qcstring.h:34
const char * inputString
Definition lexscanner.l:60
QCString cCodeBuffer
Definition lexscanner.l:81
ClangTUParser * clangParser
Definition lexscanner.l:85
std::shared_ptr< Entry > current
Definition lexscanner.l:87
std::shared_ptr< Entry > current_root
Definition lexscanner.l:88
COutlineParser cOutlineParser
Definition lexscanner.l:59
QCString docBlockName
Definition lexscanner.l:73
SrcLangExt language
Definition lexscanner.l:89
SrcLangExt
Language as given by extension.
Definition types.h:42
A bunch of utility functions.
107%}
108
109nl (\r\n|\r|\n)
110ws [ \t]
111nws [^ \t\n]
112TopStart "%top{"{nl}
113TopEnd "}"{nl}
114LiteralStart "%{"{nl}
115LiteralEnd "%}"{nl}
116Option "%option"
117RulesStart "%%"{nl}
118RulesEnd "%%"{nl}
119RulesSharp "<"[^>\n]*">"
120RulesCurly "{"[^{}\n]*"}"
121StartSquare "["
122StartDouble "\""
123StartRound "("
124StartRoundQuest "(?"
125EscapeRulesCharOpen "\\["|"\<"|"\\{"|"\\‍("|"\\\""|"\\ "|"\\\\"
126EscapeRulesCharClose "\\]"|"\>"|"\\}"|"\\‍)"
127EscapeRulesChar {EscapeRulesCharOpen}|{EscapeRulesCharClose}
128
129CMD ("\\"|"@")
130BN [ \t\n\r]
131BL [ \t\r]*"\n"
132B [ \t]
133Bopt {B}*
134ID [$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*
135PRE [pP][rR][eE]
136CODE [cC][oO][dD][eE]
137RAWBEGIN (u|U|L|u8)?R\"[^ \t\‍(\‍)\\]{0,16}"("
138RAWEND ")"[^ \t\‍(\‍)\\]{0,16}\"
139CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
140CHARCE "[:"[^:]*":]"
141 /* no comment start / end signs inside square brackets */
142NCOMM [^/\*]
143 // C start comment
144CCS "/\*"
145 // C end comment
146CCE "*\/"
147 // Cpp comment
148CPPC "/\/"
149 // doxygen start comment
150DCOMM ("/\*!"|"/\**"|"/\/!"|"/\/\/")
151
152 // Optional any character
153ANYopt .*
154 // Optional all but newline
155NONLopt [^\n]*
156
157%x DefSection
158%x Option
159%x OptPrefix
160%x DefSectionLine
161%x RulesSectionInit
162%x RulesPattern
163%x RulesDouble
164%x RulesRoundDouble
165%x RulesSquare
166%x RulesRoundSquare
167%x RulesRound
168%x RulesRoundQuest
169%x UserSection
170
171%x TopSection
172%x LiteralSection
173
174%x COMMENT
175
176%x SkipCurly
177%x SkipCurlyEndDoc
178%x PreLineCtrl
179%x DocLine
180%x DocBlock
181%x DocCopyBlock
182%x SkipString
183%x RawString
184%x SkipComment
185%x SkipCxxComment
186%x Comment
187
189
190<*>\x0d
191<DefSection>{Option} {
192 BEGIN (Option);
193 }
194<Option>"prefix"{ws}*"="{ws}* {
195 BEGIN (OptPrefix);
196 }
197<OptPrefix>"\""[^\"]*"\"" {
198 yyextra->prefix = yytext;
199 yyextra->prefix = yyextra->prefix.mid(1,yyleng-2);
200 BEGIN (Option);
201 }
202<Option>"reentrant" {
203 yyextra-> reentrant = true;
204 }
205<Option>"bison-bridge" {
206 yyextra-> bison_bridge = true;
207 }
208<Option>"bison-locations" {
209 yyextra-> bison_bridge = true;
210 yyextra-> bison_locations = true;
211 }
212<Option>{nws}+
213<Option>{ws}+
214<Option>{nl} {
215 yyextra->cCodeBuffer += yytext;
216 BEGIN (DefSection);
217 }
218<DefSection>^{RulesStart} {
219 {
220 bool fill = false;
221 yyextra->cCodeBuffer += "int " + yyextra->prefix + "lex (";
222 if (yyextra->bison_bridge )
223 {
224 if (fill) yyextra->cCodeBuffer += ",";
225 yyextra->cCodeBuffer += "YYSTYPE * yylval_param";
226 fill = true;
227 }
228 if (yyextra->bison_locations)
229 {
230 if (fill) yyextra->cCodeBuffer += ",";
231 yyextra->cCodeBuffer += "YYLTYPE * yylloc_param";
232 fill = true;
233 }
234 if (yyextra->reentrant)
235 {
236 if (fill) yyextra->cCodeBuffer += ",";
237 yyextra->cCodeBuffer += "yyscan_t yyscanner";
238 fill = true;
239 }
240 if (!yyextra->bison_bridge && !yyextra->bison_locations && !yyextra->reentrant)
241 {
242 yyextra->cCodeBuffer += "void";
243 }
244 yyextra->cCodeBuffer += ") {\n";
245 }
246 BEGIN (RulesSectionInit);
247 }
248<DefSection>^{TopStart} {
249 yyextra->cCodeBuffer += "\n";
250 yyextra->lastContext = YY_START;
251 BEGIN (TopSection);
252 }
253<DefSection>^{LiteralStart} {
254 yyextra->cCodeBuffer += "\n";
255 yyextra->lastContext = YY_START;
256 BEGIN (LiteralSection);
257 }
258<TopSection>^{TopEnd} {
259 yyextra->cCodeBuffer += "\n";
260 BEGIN( yyextra->lastContext ) ;
261 }
262<TopSection>.*{nl} {
263 yyextra->cCodeBuffer += yytext;
264 }
265<LiteralSection>^{LiteralEnd} {
266 yyextra->cCodeBuffer += "\n";
267 BEGIN( yyextra->lastContext ) ;
268 }
269<LiteralSection>.*{nl} {
270 yyextra->cCodeBuffer += yytext;
271 }
272<DefSection>^{nws} {
273 BEGIN(DefSectionLine);
274 }
275<DefSection>{CPPC}.*{nl} {
276 yyextra->cCodeBuffer += yytext;
277 }
278<DefSection>^{ws}*{CCS} {
279 yyextra->cCodeBuffer += yytext;
280 yyextra->lastContext = YY_START;
281 BEGIN(COMMENT);
282 }
283<COMMENT>{CCE}{ws}*{nl} {
284 yyextra->cCodeBuffer+=yytext;
285 BEGIN(yyextra->lastContext);
286 }
287<COMMENT>{CCE} {
288 yyextra->cCodeBuffer+=yytext;
289 BEGIN(yyextra->lastContext);
290 }
291<COMMENT>[^*\n]+ {
292 yyextra->cCodeBuffer += yytext;
293 }
294<COMMENT>{CPPC}|{CCS} {
295 yyextra->cCodeBuffer += yytext;
296 }
297<COMMENT>{nl} {
298 yyextra->cCodeBuffer += yytext;
299 }
300<COMMENT>. {
301 yyextra->cCodeBuffer += yytext;
302 }
303<DefSection>^{nl} {
304 yyextra->cCodeBuffer += "\n";
305 }
306<DefSection>^{ws}.*{nl} {
307 yyextra->cCodeBuffer += yytext;
308 }
309<DefSectionLine>.*{nl} {
310 yyextra->cCodeBuffer += "\n";
311 BEGIN(DefSection);
312 }
313<RulesSectionInit,RulesPattern>^{RulesEnd} {
314 yyextra->cCodeBuffer += "}\n";
315 BEGIN (UserSection);
316 }
317<RulesSectionInit>^{nws} {
318 unput(*yytext);
319 BEGIN(RulesPattern);
320 }
321<RulesSectionInit>^{ws}.*{nl} {
322 yyextra->cCodeBuffer += yytext;
323 }
324<RulesSectionInit>^{nl} {
325 yyextra->cCodeBuffer += yytext;
326 }
327<RulesPattern>"<<EOF>>" {
328 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
329 }
#define repeatChar(chr, cnt)
Definition lexscanner.l:55
330<RulesPattern>{EscapeRulesChar} {
331 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
332 }
333<RulesPattern>{RulesSharp} {
334 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
335 }
336<RulesPattern>{RulesCurly} {
337 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
338 }
339<RulesPattern>{StartDouble} {
340 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
341 yyextra->lastContext = YY_START;
342 BEGIN(RulesDouble);
343 }
344<RulesDouble,RulesRoundDouble>"\\\\" {
345 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
346 }
347<RulesDouble,RulesRoundDouble>"\\\"" {
348 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
349 }
350<RulesDouble>"\"" {
351 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
352 BEGIN( yyextra->lastContext ) ;
353 }
354<RulesRoundDouble>"\"" {
355 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
356 BEGIN(RulesRound) ;
357 }
358<RulesDouble,RulesRoundDouble>. {
359 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
360 }
361<RulesPattern>{StartSquare} {
362 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
363 yyextra->lastContext = YY_START;
364 BEGIN(RulesSquare);
365 }
366<RulesSquare,RulesRoundSquare>{CHARCE} {
367 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
368 }
369<RulesSquare,RulesRoundSquare>"\\[" |
370<RulesSquare,RulesRoundSquare>"\\]" {
371 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
372 }
373<RulesSquare>"]" {
374 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
375 BEGIN(RulesPattern);
376 }
377<RulesRoundSquare>"]" {
378 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
379 BEGIN(RulesRound) ;
380 }
381<RulesSquare,RulesRoundSquare>"\\\\" {
382 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
383 }
384<RulesSquare,RulesRoundSquare>. {
385 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
386 }
387<RulesPattern>{StartRoundQuest} {
388 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
389 yyextra->lastContext = YY_START;
390 BEGIN(RulesRoundQuest);
391 }
392<RulesRoundQuest>{nl} {
393 yyextra->cCodeBuffer += "\n";
394 }
395<RulesRoundQuest>[^)] {
396 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
397 }
398<RulesRoundQuest>")" {
399 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
400 BEGIN(yyextra->lastContext);
401 }
402<RulesPattern>{StartRound} {
403 yyextra->roundCount++;
404 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
405 yyextra->lastContext = YY_START;
406 BEGIN(RulesRound);
407 }
408<RulesRound>{RulesCurly} {
409 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
410 }
411<RulesRound>{StartSquare} {
412 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
413 BEGIN(RulesRoundSquare);
414 }
415<RulesRound>{StartDouble} {
416 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
417 BEGIN(RulesRoundDouble);
418 }
419<RulesRound>{EscapeRulesChar} {
420 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
421 }
422<RulesRound>"(" {
423 yyextra->roundCount++;
424 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
425 }
426<RulesRound>")" {
427 yyextra->roundCount--;
428 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
429 if (!yyextra->roundCount) BEGIN( yyextra->lastContext ) ;
430 }
431<RulesRound>{nl} {
432 yyextra->cCodeBuffer += "\n";
433 }
434<RulesRound>{ws} {
435 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
436 }
437<RulesRound>. {
438 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
439 }
440<RulesPattern>{ws}+"|" {
441 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
442 yyextra->curlyCount = 0;
443 BEGIN(SkipCurly);
444 }
445<RulesPattern>^{ws}*{nl} {
446 yyextra->cCodeBuffer += "\n";
447 }
448<RulesPattern>^{ws}+ {
449 }
450
451<RulesPattern>({ws}|{nl}) {
452 unput(*yytext);
453 yyextra->curlyCount = 0;
454 BEGIN(SkipCurly);
455 }
456<RulesPattern>"\\\\" {
457 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
458 }
459<RulesPattern>{CCS} {
460 yyextra->cCodeBuffer += yytext;
461 yyextra->lastContext = YY_START;
462 BEGIN(COMMENT);
463 }
464<RulesPattern>. {
465 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
466 }
467<SkipCurly>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
468 yyextra->cCodeBuffer += yytext;
469 yyextra->lastPreLineCtrlContext = YY_START;
470 BEGIN( PreLineCtrl );
471 }
472<PreLineCtrl>"\""[^\n\"]*"\"" {
473 yyextra->cCodeBuffer += yytext;
474 }
475<PreLineCtrl>. {
476 yyextra->cCodeBuffer += yytext;
477 }
478<PreLineCtrl>\n {
479 yyextra->cCodeBuffer += yytext;
480 BEGIN( yyextra->lastPreLineCtrlContext );
481 }
482<SkipCurly>"{" {
483 yyextra->cCodeBuffer += yytext;
484 ++yyextra->curlyCount ;
485 }
486<SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */
487<SkipCurly>"}" {
488 yyextra->cCodeBuffer += yytext;
489 if( yyextra->curlyCount )
490 {
491 --yyextra->curlyCount ;
492 }
493 }
494<SkipCurly>"}"{BN}*{DCOMM}"<" {
495 yyextra->cCodeBuffer += yytext;
496 if ( yyextra->curlyCount )
497 {
498 --yyextra->curlyCount ;
499 }
500 else
501 {
502 yyextra->docBlockContext = SkipCurlyEndDoc;
503 if (yytext[yyleng-3]=='/')
504 {
505 BEGIN( DocLine );
506 }
507 else
508 {
509 BEGIN( DocBlock );
510 }
511 }
512 }
513<SkipCurly>\" {
514 yyextra->cCodeBuffer += yytext;
515 yyextra->lastStringContext=SkipCurly;
516 BEGIN( SkipString );
517 }
518<SkipCurly>^{B}*"#" {
519 yyextra->cCodeBuffer += yytext;
520 yyextra->lastPreLineCtrlContext = YY_START;
521 BEGIN( PreLineCtrl );
522 }
523<SkipCurly>{B}*{RAWBEGIN} {
524 QCString raw=QCString(yytext).stripWhiteSpace();
525 yyextra->delimiter = raw.mid(2);
526 yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
527 yyextra->lastRawStringContext = YY_START;
528 yyextra->cCodeBuffer += yytext;
529 BEGIN(RawString);
530 }
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
QCString left(size_t len) const
Definition qcstring.h:214
531<SkipCurly>[^\n#"'@\\/{}<]+ {
532 yyextra->cCodeBuffer += yytext;
533 }
534<SkipCurly>{CCS} {
535 yyextra->cCodeBuffer += yytext;
536 yyextra->lastCContext = YY_START;
537 BEGIN(SkipComment);
538 }
539<SkipCurly>{CPPC} {
540 yyextra->cCodeBuffer += yytext;
541 yyextra->lastCContext = YY_START;
542 BEGIN(SkipCxxComment);
543 }
544<SkipCurly>{CHARLIT} {
545 yyextra->cCodeBuffer += yytext;
546 }
547<SkipCurly>\' {
548 yyextra->cCodeBuffer += yytext;
549 }
550<SkipCurly>. {
551 yyextra->cCodeBuffer += yytext;
552 }
553<SkipCurly>({CPPC}{B}*)?{CCS}"!" {
554 yyextra->cCodeBuffer += yytext;
555 yyextra->docBlockContext = YY_START;
556 BEGIN( DocBlock );
557 }
558<SkipCurly>{CCS}"*"[*]+{BL} {
559 bool javadocBanner = Config_getBool(JAVADOC_BANNER);
560 yyextra->cCodeBuffer += yytext;
561 if( javadocBanner )
562 {
563 yyextra->docBlockContext = YY_START;
564 BEGIN( DocBlock );
565 }
566 else
567 {
568 BEGIN( Comment ) ;
569 }
570 }
#define Config_getBool(name)
Definition config.h:33
571<SkipCurly>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
572 yyextra->cCodeBuffer += yytext;
573 yyextra->docBlockContext = YY_START;
574 BEGIN( DocBlock );
575 }
576<SkipCurly>{CPPC}"!" {
577 yyextra->cCodeBuffer += yytext;
578 yyextra->docBlockContext = YY_START;
579 BEGIN( DocLine );
580 }
581<SkipCurly>{CPPC}"/"/[^/] {
582 yyextra->cCodeBuffer += yytext;
583 yyextra->docBlockContext = YY_START;
584 BEGIN( DocLine );
585 }
586
587<SkipCurly>\n {
588 yyextra->cCodeBuffer += yytext;
589 if (yyextra->curlyCount<=0)
590 {
591 BEGIN(RulesPattern);
592 }
593 }
594<SkipString>\\. {
595 yyextra->cCodeBuffer += yytext;
596 }
597<SkipString>\" {
598 yyextra->cCodeBuffer += yytext;
599 BEGIN( yyextra->lastStringContext );
600 }
601<SkipString>{CCS}|{CCE}|{CPPC} {
602 yyextra->cCodeBuffer += yytext;
603 }
604<SkipString>\n {
605 yyextra->cCodeBuffer += yytext;
606 }
607<SkipString>. {
608 yyextra->cCodeBuffer += yytext;
609 }
610<SkipCxxComment>.*"\\\n" { // line continuation
611 yyextra->cCodeBuffer += yytext;
612 }
613<SkipCxxComment>{ANYopt}/\n {
614 yyextra->cCodeBuffer += yytext;
615 BEGIN( yyextra->lastCContext ) ;
616 }
617<Comment>{BN}+ {
618 yyextra->cCodeBuffer += yytext ;
619 }
620<Comment>{CCS} { yyextra->cCodeBuffer += yytext ; }
621<Comment>{CPPC} { yyextra->cCodeBuffer += yytext ; }
622<Comment>{CMD}("code"|"verbatim"|"iliteral") {
623 yyextra->insideCode=TRUE;
624 yyextra->cCodeBuffer += yytext ;
625 }
#define TRUE
Definition qcstring.h:37
626<Comment>{CMD}("endcode"|"endverbatim"|"endiliteral") {
627 yyextra->insideCode=FALSE;
628 yyextra->cCodeBuffer += yytext ;
629 }
630<Comment>[^ \.\t\r\n\/\*]+ { yyextra->cCodeBuffer += yytext ; }
631<Comment>{CCE} { yyextra->cCodeBuffer += yytext ;
632 if (!yyextra->insideCode) BEGIN( yyextra->lastContext ) ;
633 }
634<Comment>. { yyextra->cCodeBuffer += *yytext ; }
635
636<SkipComment>{CPPC}|{CCS} {
637 yyextra->cCodeBuffer += yytext;
638 }
639<SkipComment>[^\*\n]+ {
640 yyextra->cCodeBuffer += yytext;
641 }
642<SkipComment>\n {
643 yyextra->cCodeBuffer += yytext;
644 }
645<SkipComment>{B}*{CCE} {
646 yyextra->cCodeBuffer += yytext;
647 BEGIN( yyextra->lastCContext );
648 }
649<SkipComment>"*" {
650 yyextra->cCodeBuffer += yytext;
651 }
652<RawString>{RAWEND} {
653 yyextra->cCodeBuffer += yytext;
654 QCString delimiter = yytext+1;
655 delimiter=delimiter.left(delimiter.length()-1);
656 if (delimiter==yyextra->delimiter)
657 {
658 BEGIN(yyextra->lastRawStringContext);
659 }
660 }
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
661<RawString>[^)\n]+ {
662 yyextra->cCodeBuffer += yytext;
663 }
664<RawString>. {
665 yyextra->cCodeBuffer += yytext;
666 }
667<RawString>\n {
668 yyextra->cCodeBuffer += yytext;
669 }
670
671
672 /* ---- Single line comments ------ */
673<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
674 yyextra->cCodeBuffer += yytext;
675 }
676<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
677 yyextra->cCodeBuffer += yytext;
678 BEGIN( yyextra->docBlockContext );
679 }
680<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
681 yyextra->cCodeBuffer += yytext;
682 BEGIN( yyextra->docBlockContext );
683 }
684<DocLine>{NONLopt}/"\n" { // whole line
685 yyextra->cCodeBuffer += yytext;
686 BEGIN( yyextra->docBlockContext );
687 }
688
689 /* ---- Comments blocks ------ */
690
691<DocBlock>"*"*{CCE} { // end of comment block
692 yyextra->cCodeBuffer += yytext;
693 BEGIN(yyextra->docBlockContext);
694 }
695<DocBlock>^{B}*"*"+/[^/] {
696 yyextra->cCodeBuffer += yytext;
697 }
698<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
699 yyextra->cCodeBuffer += yytext;
700 }
701<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
702 yyextra->cCodeBuffer += yytext;
703 }
704<DocBlock>{CPPC} { // slashes in the middle of a comment block
705 yyextra->cCodeBuffer += yytext;
706 }
707<DocBlock>{CCS} { // start of a new comment in the
708 // middle of a comment block
709 yyextra->cCodeBuffer += yytext;
710 }
711<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
712 yyextra->cCodeBuffer += yytext;
713 }
714<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
715 yyextra->cCodeBuffer += yytext;
716 yyextra->docBlockName=&yytext[1];
717 if (yyextra->docBlockName.at(1)=='[')
718 {
719 yyextra->docBlockName.at(1)=']';
720 }
721 if (yyextra->docBlockName.at(1)=='{')
722 {
723 yyextra->docBlockName.at(1)='}';
724 }
725 if (yyextra->docBlockName.at(1)=='(')
726 {
727 yyextra->docBlockName.at(1)=')';
728 }
729 yyextra->fencedSize=0;
730 yyextra->nestedComment=FALSE;
731 BEGIN(DocCopyBlock);
732 }
733<DocBlock>{B}*"<"{PRE}">" {
734 yyextra->cCodeBuffer += yytext;
735 yyextra->docBlockName="<pre>";
736 yyextra->fencedSize=0;
737 yyextra->nestedComment=FALSE;
738 BEGIN(DocCopyBlock);
739 }
740<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
741 yyextra->cCodeBuffer += yytext;
742 yyextra->docBlockName="uml";
743 yyextra->fencedSize=0;
744 yyextra->nestedComment=FALSE;
745 BEGIN(DocCopyBlock);
746 }
747<DocBlock>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
748 yyextra->cCodeBuffer += yytext;
749 yyextra->docBlockName=&yytext[1];
750 yyextra->fencedSize=0;
751 yyextra->nestedComment=FALSE;
752 BEGIN(DocCopyBlock);
753 }
754<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
755 yyextra->cCodeBuffer += yytext;
756 QCString pat = substitute(yytext,"*"," ");
757 yyextra->docBlockName="~~~";
758 yyextra->fencedSize=pat.stripWhiteSpace().length();
759 yyextra->nestedComment=FALSE;
760 BEGIN(DocCopyBlock);
761 }
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
762<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
763 yyextra->cCodeBuffer += yytext;
764 QCString pat = substitute(yytext,"*"," ");
765 yyextra->docBlockName="```";
766 yyextra->fencedSize=pat.stripWhiteSpace().length();
767 yyextra->nestedComment=FALSE;
768 BEGIN(DocCopyBlock);
769 }
770<DocBlock>{B}*"<code>" {
771 REJECT;
772 }
773<DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
774 yyextra->cCodeBuffer += yytext;
775 }
776<DocBlock>\n { // newline
777 yyextra->cCodeBuffer += yytext;
778 }
779<DocBlock>. { // command block
780 yyextra->cCodeBuffer += yytext;
781 }
782 /* ---- Copy verbatim sections ------ */
783
784<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
785 yyextra->cCodeBuffer += yytext;
786 if (yyextra->docBlockName=="<pre>")
787 {
788 BEGIN(DocBlock);
789 }
790 }
791<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
792 yyextra->cCodeBuffer += yytext;
793 if (yyextra->docBlockName=="<code>")
794 {
795 BEGIN(DocBlock);
796 }
797 }
798<DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
799 yyextra->cCodeBuffer += yytext;
800 if (yyextra->docBlockName==&yytext[1])
801 {
802 BEGIN(DocBlock);
803 }
804 }
805<DocCopyBlock>[\\@]("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
806 yyextra->cCodeBuffer += yytext;
807 if (yyextra->docBlockName==&yytext[4])
808 {
809 BEGIN(DocBlock);
810 }
811 }
812<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
813 yyextra->cCodeBuffer += yytext;
814 if ((yyextra->docBlockName=="verbatim") || (yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
815 {
816 REJECT;
817 }
818 else
819 {
820 yyextra->cCodeBuffer += yytext;
821 }
822 }
823<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
824 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
825 {
826 yyextra->cCodeBuffer += yytext;
827 }
828 else
829 {
830 REJECT;
831 }
832 }
833<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
834 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
835 {
836 yyextra->cCodeBuffer += yytext;
837 }
838 else
839 {
840 REJECT;
841 }
842 }
843<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
844 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
845 {
846 if (yyextra->nestedComment) // keep * it is part of the code
847 {
848 yyextra->cCodeBuffer += yytext;
849 }
850 else // remove * it is part of the comment block
851 {
852 yyextra->cCodeBuffer += yytext;
853 }
854 }
855 else
856 {
857 REJECT;
858 }
859 }
860<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
861 yyextra->cCodeBuffer += yytext;
862 QCString pat = substitute(yytext,"*"," ");
863 if (yyextra->docBlockName == "~~~" && yyextra->fencedSize==pat.stripWhiteSpace().length())
864 {
865 BEGIN(DocBlock);
866 }
867 }
868<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
869 yyextra->cCodeBuffer += yytext;
870 QCString pat = substitute(yytext,"*"," ");
871 if (yyextra->docBlockName == "```" && yyextra->fencedSize==pat.stripWhiteSpace().length())
872 {
873 BEGIN(DocBlock);
874 }
875 }
876<DocCopyBlock>[^<@/\*\]~\$\\\n]+ { // any character that is not special
877 yyextra->cCodeBuffer += yytext;
878 }
879<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
880 if (yytext[1]=='*')
881 {
882 yyextra->nestedComment=TRUE;
883 }
884 else if (yytext[0]=='*')
885 {
886 yyextra->nestedComment=FALSE;
887 }
888 yyextra->cCodeBuffer += yytext;
889 }
890<DocCopyBlock>\n { // newline
891 yyextra->cCodeBuffer += yytext;
892 }
893<DocCopyBlock>. { // any other character
894 yyextra->cCodeBuffer += yytext;
895 }
896<SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
897 yyextra->docBlockContext = SkipCurlyEndDoc;
898 yyextra->cCodeBuffer += yytext;
899 if (yytext[yyleng-3]=='/')
900 {
901 BEGIN( DocLine );
902 }
903 else
904 {
905 BEGIN( DocBlock );
906 }
907 }
908<SkipCurlyEndDoc>"}" {
909 yyextra->cCodeBuffer += yytext;
910 BEGIN(SkipCurly);
911 }
912
913<UserSection>.*{nl} {
914 yyextra->cCodeBuffer += yytext;
915 }
916
917
918 /*
919<*>. { fprintf(stderr,"Lex scanner Def rule for %s: #%s#\n",stateToString(YY_START),yytext);}
920<*>{nl} { fprintf(stderr,"Lex scanner Def rule for newline %s: #%s#\n",stateToString(YY_START),yytext);}
921 */
922<*><<EOF>> {
923 handleCCode(yyscanner);
924 yyterminate();
925 }
#define yyterminate()
static void handleCCode(yyscan_t yyscanner)
Definition lexcode.l:1140
926%%
927
928//----------------------------------------------------------------------------
929static int yyread(yyscan_t yyscanner,char *buf,int max_size)
930{
931 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
932 int c=0;
933 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
934 {
935 *buf = yyextra->inputString[yyextra->inputPosition++] ;
936 //printf("%d (%c)\n",*buf,*buf);
937 c++; buf++;
938 }
939 return c;
940}
941
942//-----------------------------------------------------------------------------
943
944static void parseMain(yyscan_t yyscanner,
945 const QCString &fileName,
946 const char *fileBuf,
947 const std::shared_ptr<Entry> &rt,
948 ClangTUParser *clangParser)
949{
950 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
951
952 yyextra->inputString = fileBuf;
953 yyextra->inputPosition = 0;
954 lexscannerYYrestart(0,yyscanner);
955
956 yyextra->current_root = rt;
957 yyextra->fileName = fileName;
958 yyextra->clangParser = clangParser;
959 yyextra->language = getLanguageFromFileName(yyextra->fileName);
960 rt->lang = yyextra->language;
961 msg("Parsing file %s...\n",qPrint(yyextra->fileName));
962
963 yyextra->current_root = rt;
964 yyextra->current = std::make_shared<Entry>();
965 EntryType sec=guessSection(yyextra->fileName);
966 if (!sec.isEmpty())
967 {
968 yyextra->current->name = yyextra->fileName;
969 yyextra->current->section = EntryType(sec);
970 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
971 }
972 yyextra->current->reset();
973 BEGIN( DefSection );
974
975 lexscannerYYlex(yyscanner);
976
977 rt->program.str(std::string());
978}
979
980//----------------------------------------------------------------------------
981
982
983static void handleCCode(yyscan_t yyscanner)
984{
985 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
986
987 if (yyextra->cCodeBuffer.isEmpty()) return;
988 yyextra->cOutlineParser.parseInput(yyextra->fileName,
989 yyextra->cCodeBuffer.data(),
990 yyextra->current_root,
991 yyextra->clangParser);
992 yyextra->cCodeBuffer.clear();
993 return;
994}
995//----------------------------------------------------------------------------
996
1002
1004{
1005 lexscannerYYlex_init_extra(&p->state,&p->yyscanner);
1006#ifdef FLEX_DEBUG
1007 lexscannerYYset_debug(Debug::isFlagSet(Debug::Lex_lexscanner)?1:0,p->yyscanner);
1008#endif
1009}
1010
1012{
1013 lexscannerYYlex_destroy(p->yyscanner);
1014}
1015
1017 const char *fileBuf,
1018 const std::shared_ptr<Entry> &root,
1019 ClangTUParser *clangParser)
1020{
1021 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
1022
1023 yyextra->fileName = fileName;
1024 DebugLex debugLex(Debug::Lex_lexscanner, __FILE__, qPrint(fileName));
1025
1026 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
1027}
1028
1029
1030//----------------------------------------------------------------------------
1031
1032#include "lexscanner.l.h"
@ Lex_lexscanner
Definition debug.h:62
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:135
Wrapper class for the Entry type.
Definition types.h:631
~LexOutlineParser() override
std::unique_ptr< Private > p
Definition lexscanner.h:42
void parseInput(const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &root, ClangTUParser *clangParser) override
Parses a single input file with the goal to build an Entry tree.
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3980
static void parseMain(yyscan_t yyscanner, const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt, FortranFormat format)
void msg(const char *fmt,...)
Definition message.cpp:98
const char * qPrint(const char *s)
Definition qcstring.h:672
lexscannerYY_state state
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5549
EntryType guessSection(const QCString &name)
Definition util.cpp:349