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 stateful 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:927
static const char * stateToString(int state)
static void handleCCode(yyscan_t yyscanner)
Definition lexscanner.l:981
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
Definition types.h:207
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 char *p=yytext;
525 while (*p && qisspace(*p)) p++;
526 yyextra->delimiter = extractBeginRawStringDelimiter(p);
527 yyextra->lastRawStringContext = YY_START;
528 yyextra->cCodeBuffer += yytext;
529 BEGIN(RawString);
530 }
bool qisspace(char c)
Definition qcstring.h:81
QCString extractBeginRawStringDelimiter(const char *rawStart)
Definition util.cpp:7451
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 if (extractEndRawStringDelimiter(yytext)==yyextra->delimiter)
655 {
656 BEGIN(yyextra->lastRawStringContext);
657 }
658 }
QCString extractEndRawStringDelimiter(const char *rawEnd)
Definition util.cpp:7459
659<RawString>[^)\n]+ {
660 yyextra->cCodeBuffer += yytext;
661 }
662<RawString>. {
663 yyextra->cCodeBuffer += yytext;
664 }
665<RawString>\n {
666 yyextra->cCodeBuffer += yytext;
667 }
668
669
670 /* ---- Single line comments ------ */
671<DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
672 yyextra->cCodeBuffer += yytext;
673 }
674<DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
675 yyextra->cCodeBuffer += yytext;
676 BEGIN( yyextra->docBlockContext );
677 }
678<DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
679 yyextra->cCodeBuffer += yytext;
680 BEGIN( yyextra->docBlockContext );
681 }
682<DocLine>{NONLopt}/"\n" { // whole line
683 yyextra->cCodeBuffer += yytext;
684 BEGIN( yyextra->docBlockContext );
685 }
686
687 /* ---- Comments blocks ------ */
688
689<DocBlock>"*"*{CCE} { // end of comment block
690 yyextra->cCodeBuffer += yytext;
691 BEGIN(yyextra->docBlockContext);
692 }
693<DocBlock>^{B}*"*"+/[^/] {
694 yyextra->cCodeBuffer += yytext;
695 }
696<DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
697 yyextra->cCodeBuffer += yytext;
698 }
699<DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
700 yyextra->cCodeBuffer += yytext;
701 }
702<DocBlock>{CPPC} { // slashes in the middle of a comment block
703 yyextra->cCodeBuffer += yytext;
704 }
705<DocBlock>{CCS} { // start of a new comment in the
706 // middle of a comment block
707 yyextra->cCodeBuffer += yytext;
708 }
709<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
710 yyextra->cCodeBuffer += yytext;
711 }
712<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
713 yyextra->cCodeBuffer += yytext;
714 yyextra->docBlockName=&yytext[1];
715 if (yyextra->docBlockName.at(1)=='[')
716 {
717 yyextra->docBlockName.at(1)=']';
718 }
719 if (yyextra->docBlockName.at(1)=='{')
720 {
721 yyextra->docBlockName.at(1)='}';
722 }
723 if (yyextra->docBlockName.at(1)=='(')
724 {
725 yyextra->docBlockName.at(1)=')';
726 }
727 yyextra->fencedSize=0;
728 yyextra->nestedComment=FALSE;
729 BEGIN(DocCopyBlock);
730 }
731<DocBlock>{B}*"<"{PRE}">" {
732 yyextra->cCodeBuffer += yytext;
733 yyextra->docBlockName="<pre>";
734 yyextra->fencedSize=0;
735 yyextra->nestedComment=FALSE;
736 BEGIN(DocCopyBlock);
737 }
738<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
739 yyextra->cCodeBuffer += yytext;
740 yyextra->docBlockName="uml";
741 yyextra->fencedSize=0;
742 yyextra->nestedComment=FALSE;
743 BEGIN(DocCopyBlock);
744 }
745<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!)
746 yyextra->cCodeBuffer += yytext;
747 yyextra->docBlockName=&yytext[1];
748 yyextra->fencedSize=0;
749 yyextra->nestedComment=FALSE;
750 BEGIN(DocCopyBlock);
751 }
752<DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
753 yyextra->cCodeBuffer += yytext;
754 QCString pat = substitute(yytext,"*"," ");
755 yyextra->docBlockName="~~~";
756 yyextra->fencedSize=pat.stripWhiteSpace().length();
757 yyextra->nestedComment=FALSE;
758 BEGIN(DocCopyBlock);
759 }
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
760<DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
761 yyextra->cCodeBuffer += yytext;
762 QCString pat = substitute(yytext,"*"," ");
763 yyextra->docBlockName="```";
764 yyextra->fencedSize=pat.stripWhiteSpace().length();
765 yyextra->nestedComment=FALSE;
766 BEGIN(DocCopyBlock);
767 }
768<DocBlock>{B}*"<code>" {
769 REJECT;
770 }
771<DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
772 yyextra->cCodeBuffer += yytext;
773 }
774<DocBlock>\n { // newline
775 yyextra->cCodeBuffer += yytext;
776 }
777<DocBlock>. { // command block
778 yyextra->cCodeBuffer += yytext;
779 }
780 /* ---- Copy verbatim sections ------ */
781
782<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
783 yyextra->cCodeBuffer += yytext;
784 if (yyextra->docBlockName=="<pre>")
785 {
786 BEGIN(DocBlock);
787 }
788 }
789<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
790 yyextra->cCodeBuffer += yytext;
791 if (yyextra->docBlockName=="<code>")
792 {
793 BEGIN(DocBlock);
794 }
795 }
796<DocCopyBlock>{CMD}("f$"|"f]"|"f}"|"f)") {
797 yyextra->cCodeBuffer += yytext;
798 if (yyextra->docBlockName==&yytext[1])
799 {
800 BEGIN(DocBlock);
801 }
802 }
803<DocCopyBlock>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
804 yyextra->cCodeBuffer += yytext;
805 if (yyextra->docBlockName==&yytext[4])
806 {
807 BEGIN(DocBlock);
808 }
809 }
810<DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
811 yyextra->cCodeBuffer += yytext;
812 if ((yyextra->docBlockName=="verbatim") || (yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
813 {
814 REJECT;
815 }
816 else
817 {
818 yyextra->cCodeBuffer += yytext;
819 }
820 }
821<DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
822 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
823 {
824 yyextra->cCodeBuffer += yytext;
825 }
826 else
827 {
828 REJECT;
829 }
830 }
831<DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
832 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
833 {
834 yyextra->cCodeBuffer += yytext;
835 }
836 else
837 {
838 REJECT;
839 }
840 }
841<DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
842 if ((yyextra->docBlockName=="code") || (yyextra->docBlockName=="iliteral"))
843 {
844 if (yyextra->nestedComment) // keep * it is part of the code
845 {
846 yyextra->cCodeBuffer += yytext;
847 }
848 else // remove * it is part of the comment block
849 {
850 yyextra->cCodeBuffer += yytext;
851 }
852 }
853 else
854 {
855 REJECT;
856 }
857 }
858<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
859 yyextra->cCodeBuffer += yytext;
860 QCString pat = substitute(yytext,"*"," ");
861 if (yyextra->docBlockName == "~~~" && yyextra->fencedSize==pat.stripWhiteSpace().length())
862 {
863 BEGIN(DocBlock);
864 }
865 }
866<DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
867 yyextra->cCodeBuffer += yytext;
868 QCString pat = substitute(yytext,"*"," ");
869 if (yyextra->docBlockName == "```" && yyextra->fencedSize==pat.stripWhiteSpace().length())
870 {
871 BEGIN(DocBlock);
872 }
873 }
874<DocCopyBlock>[^<@/\*\]~\$\\\n]+ { // any character that is not special
875 yyextra->cCodeBuffer += yytext;
876 }
877<DocCopyBlock>{CCS}|{CCE}|{CPPC} {
878 if (yytext[1]=='*')
879 {
880 yyextra->nestedComment=TRUE;
881 }
882 else if (yytext[0]=='*')
883 {
884 yyextra->nestedComment=FALSE;
885 }
886 yyextra->cCodeBuffer += yytext;
887 }
888<DocCopyBlock>\n { // newline
889 yyextra->cCodeBuffer += yytext;
890 }
891<DocCopyBlock>. { // any other character
892 yyextra->cCodeBuffer += yytext;
893 }
894<SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
895 yyextra->docBlockContext = SkipCurlyEndDoc;
896 yyextra->cCodeBuffer += yytext;
897 if (yytext[yyleng-3]=='/')
898 {
899 BEGIN( DocLine );
900 }
901 else
902 {
903 BEGIN( DocBlock );
904 }
905 }
906<SkipCurlyEndDoc>"}" {
907 yyextra->cCodeBuffer += yytext;
908 BEGIN(SkipCurly);
909 }
910
911<UserSection>.*{nl} {
912 yyextra->cCodeBuffer += yytext;
913 }
914
915
916 /*
917<*>. { fprintf(stderr,"Lex scanner Def rule for %s: #%s#\n",stateToString(YY_START),yytext);}
918<*>{nl} { fprintf(stderr,"Lex scanner Def rule for newline %s: #%s#\n",stateToString(YY_START),yytext);}
919 */
920<*><<EOF>> {
921 handleCCode(yyscanner);
922 yyterminate();
923 }
#define yyterminate()
static void handleCCode(yyscan_t yyscanner)
Definition lexcode.l:1139
924%%
925
926//----------------------------------------------------------------------------
927static int yyread(yyscan_t yyscanner,char *buf,int max_size)
928{
929 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
930 int c=0;
931 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
932 {
933 *buf = yyextra->inputString[yyextra->inputPosition++] ;
934 //printf("%d (%c)\n",*buf,*buf);
935 c++; buf++;
936 }
937 return c;
938}
939
940//-----------------------------------------------------------------------------
941
942static void parseMain(yyscan_t yyscanner,
943 const QCString &fileName,
944 const char *fileBuf,
945 const std::shared_ptr<Entry> &rt,
946 ClangTUParser *clangParser)
947{
948 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
949
950 yyextra->inputString = fileBuf;
951 yyextra->inputPosition = 0;
952 lexscannerYYrestart(0,yyscanner);
953
954 yyextra->current_root = rt;
955 yyextra->fileName = fileName;
956 yyextra->clangParser = clangParser;
957 yyextra->language = getLanguageFromFileName(yyextra->fileName);
958 rt->lang = yyextra->language;
959 msg("Parsing file {}...\n",yyextra->fileName);
960
961 yyextra->current_root = rt;
962 yyextra->current = std::make_shared<Entry>();
963 EntryType sec=guessSection(yyextra->fileName);
964 if (!sec.isEmpty())
965 {
966 yyextra->current->name = yyextra->fileName;
967 yyextra->current->section = EntryType(sec);
968 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
969 }
970 yyextra->current->reset();
971 BEGIN( DefSection );
972
973 lexscannerYYlex(yyscanner);
974
975 rt->program.str(std::string());
976}
977
978//----------------------------------------------------------------------------
979
980
981static void handleCCode(yyscan_t yyscanner)
982{
983 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
984
985 if (yyextra->cCodeBuffer.isEmpty()) return;
986 yyextra->cOutlineParser.parseInput(yyextra->fileName,
987 yyextra->cCodeBuffer.data(),
988 yyextra->current_root,
989 yyextra->clangParser);
990 yyextra->cCodeBuffer.clear();
991 return;
992}
993//----------------------------------------------------------------------------
994
1000
1002{
1003 lexscannerYYlex_init_extra(&p->state,&p->yyscanner);
1004#ifdef FLEX_DEBUG
1005 lexscannerYYset_debug(Debug::isFlagSet(Debug::Lex_lexscanner)?1:0,p->yyscanner);
1006#endif
1007}
1008
1010{
1011 lexscannerYYlex_destroy(p->yyscanner);
1012}
1013
1015 const char *fileBuf,
1016 const std::shared_ptr<Entry> &root,
1017 ClangTUParser *clangParser)
1018{
1019 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
1020
1021 yyextra->fileName = fileName;
1022 DebugLex debugLex(Debug::Lex_lexscanner, __FILE__, qPrint(fileName));
1023
1024 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
1025}
1026
1027
1028//----------------------------------------------------------------------------
1029
1030#include "lexscanner.l.h"
@ Lex_lexscanner
Definition debug.h:63
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
Wrapper class for the Entry type.
Definition types.h:793
~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:3992
static void parseMain(yyscan_t yyscanner, const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &rt, FortranFormat format)
#define msg(fmt,...)
Definition message.h:94
const char * qPrint(const char *s)
Definition qcstring.h:672
lexscannerYY_state state
Definition lexscanner.l:998
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5724
EntryType guessSection(const QCString &name)
Definition util.cpp:350