1 /*****************************************************************************
3 * Copyright (C) 1997-2021 by Dimitri van Heesch.
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.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
15 %option never-interactive
16 %option prefix="lexscannerYY"
18 %option extra-type="struct lexscannerYY_state *"
23 // forward declare yyscan_t to improve type safety
24 #define YY_TYPEDEF_YY_SCANNER_T
26 typedef yyguts_t *yyscan_t;
45 #include "lexscanner.h"
52 #define YY_NO_UNISTD_H 1
54 #define USE_STATE2STRING 0
56 #define repeatChar(chr, cnt) std::string(cnt, chr).c_str()
58 struct lexscannerYY_state
60 COutlineParser cOutlineParser;
61 const char * inputString = 0;
62 int inputPosition = 0;
66 int lastStringContext = 0;
67 int docBlockContext = 0;
68 int lastPreLineCtrlContext = 0;
69 int lastRawStringContext = 0;
72 bool insideCode = FALSE;
74 QCString docBlockName;
76 bool nestedComment = false;
78 QCString prefix = "yy";
79 bool reentrant = false;
80 bool bison_bridge = false;
81 bool bison_locations = false;
86 ClangTUParser *clangParser = 0;
88 std::shared_ptr<Entry> current;
89 std::shared_ptr<Entry> current_root;
94 static const char *stateToString(int state);
96 //-----------------------------------------------------------------------------
98 // forward declarations for statefull functions
99 static void handleCCode(yyscan_t yyscanner);
100 static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
102 /* ----------------------------------------------------------------- */
104 #define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
113 LiteralStart "%{"{nl}
118 RulesSharp "<"[^>\n]*">"
119 RulesCurly "{"[^{}\n]*"}"
124 EscapeRulesCharOpen "\\["|"\<"|"\\{"|"\\("|"\\\""|"\\ "|"\\\\"
125 EscapeRulesCharClose "\\]"|"\>"|"\\}"|"\\)"
126 EscapeRulesChar {EscapeRulesCharOpen}|{EscapeRulesCharClose}
133 ID [$a-z_A-Z\x80-\xFF][$a-z_A-Z0-9\x80-\xFF]*
135 CODE [cC][oO][dD][eE]
136 RAWBEGIN (u|U|L|u8)?R\"[^ \t\(\)\\]{0,16}"("
137 RAWEND ")"[^ \t\(\)\\]{0,16}\"
138 CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
140 /* no comment start / end signs inside square brackets */
148 // doxygen start comment
149 DCOMM ("/\*!"|"/\**"|"/\/!"|"/\/\/")
151 // Optional any character
153 // Optional all but newline
190 <DefSection>{Option} {
193 <Option>"prefix"{ws}*"="{ws}* {
196 <OptPrefix>"\""[^\"]*"\"" {
197 yyextra->prefix = yytext;
198 yyextra->prefix = yyextra->prefix.mid(1,yyleng-2);
201 <Option>"reentrant" {
202 yyextra-> reentrant = true;
204 <Option>"bison-bridge" {
205 yyextra-> bison_bridge = true;
207 <Option>"bison-locations" {
208 yyextra-> bison_bridge = true;
209 yyextra-> bison_locations = true;
214 yyextra->cCodeBuffer += yytext;
217 <DefSection>^{RulesStart} {
220 yyextra->cCodeBuffer += "int " + yyextra->prefix + "lex (";
221 if (yyextra->bison_bridge )
223 if (fill) yyextra->cCodeBuffer += ",";
224 yyextra->cCodeBuffer += "YYSTYPE * yylval_param";
227 if (yyextra->bison_locations)
229 if (fill) yyextra->cCodeBuffer += ",";
230 yyextra->cCodeBuffer += "YYLTYPE * yylloc_param";
233 if (yyextra->reentrant)
235 if (fill) yyextra->cCodeBuffer += ",";
236 yyextra->cCodeBuffer += "yyscan_t yyscanner";
239 if (!yyextra->bison_bridge && !yyextra->bison_locations && !yyextra->reentrant)
241 yyextra->cCodeBuffer += "void";
243 yyextra->cCodeBuffer += ") {\n";
245 BEGIN (RulesSectionInit);
247 <DefSection>^{TopStart} {
248 yyextra->cCodeBuffer += "\n";
249 yyextra->lastContext = YY_START;
252 <DefSection>^{LiteralStart} {
253 yyextra->cCodeBuffer += "\n";
254 yyextra->lastContext = YY_START;
255 BEGIN (LiteralSection);
257 <TopSection>^{TopEnd} {
258 yyextra->cCodeBuffer += "\n";
259 BEGIN( yyextra->lastContext ) ;
262 yyextra->cCodeBuffer += yytext;
264 <LiteralSection>^{LiteralEnd} {
265 yyextra->cCodeBuffer += "\n";
266 BEGIN( yyextra->lastContext ) ;
268 <LiteralSection>.*{nl} {
269 yyextra->cCodeBuffer += yytext;
272 BEGIN(DefSectionLine);
274 <DefSection>{CPPC}.*{nl} {
275 yyextra->cCodeBuffer += yytext;
277 <DefSection>^{ws}*{CCS} {
278 yyextra->cCodeBuffer += yytext;
279 yyextra->lastContext = YY_START;
282 <COMMENT>{CCE}{ws}*{nl} {
283 yyextra->cCodeBuffer+=yytext;
284 BEGIN(yyextra->lastContext);
287 yyextra->cCodeBuffer+=yytext;
288 BEGIN(yyextra->lastContext);
291 yyextra->cCodeBuffer += yytext;
293 <COMMENT>{CPPC}|{CCS} {
294 yyextra->cCodeBuffer += yytext;
297 yyextra->cCodeBuffer += yytext;
300 yyextra->cCodeBuffer += yytext;
303 yyextra->cCodeBuffer += "\n";
305 <DefSection>^{ws}.*{nl} {
306 yyextra->cCodeBuffer += yytext;
308 <DefSectionLine>.*{nl} {
309 yyextra->cCodeBuffer += "\n";
312 <RulesSectionInit,RulesPattern>^{RulesEnd} {
313 yyextra->cCodeBuffer += "}\n";
316 <RulesSectionInit>^{nws} {
320 <RulesSectionInit>^{ws}.*{nl} {
321 yyextra->cCodeBuffer += yytext;
323 <RulesSectionInit>^{nl} {
324 yyextra->cCodeBuffer += yytext;
326 <RulesPattern>"<<EOF>>" {
327 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
329 <RulesPattern>{EscapeRulesChar} {
330 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
332 <RulesPattern>{RulesSharp} {
333 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
335 <RulesPattern>{RulesCurly} {
336 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
338 <RulesPattern>{StartDouble} {
339 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
340 yyextra->lastContext = YY_START;
343 <RulesDouble,RulesRoundDouble>"\\\\" {
344 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
346 <RulesDouble,RulesRoundDouble>"\\\"" {
347 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
350 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
351 BEGIN( yyextra->lastContext ) ;
353 <RulesRoundDouble>"\"" {
354 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
357 <RulesDouble,RulesRoundDouble>. {
358 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
360 <RulesPattern>{StartSquare} {
361 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
362 yyextra->lastContext = YY_START;
365 <RulesSquare,RulesRoundSquare>{CHARCE} {
366 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
368 <RulesSquare,RulesRoundSquare>"\\[" |
369 <RulesSquare,RulesRoundSquare>"\\]" {
370 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
373 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
376 <RulesRoundSquare>"]" {
377 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
380 <RulesSquare,RulesRoundSquare>"\\\\" {
381 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
383 <RulesSquare,RulesRoundSquare>. {
384 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
386 <RulesPattern>{StartRoundQuest} {
387 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
388 yyextra->lastContext = YY_START;
389 BEGIN(RulesRoundQuest);
391 <RulesRoundQuest>{nl} {
392 yyextra->cCodeBuffer += "\n";
394 <RulesRoundQuest>[^)] {
395 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
397 <RulesRoundQuest>")" {
398 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
399 BEGIN(yyextra->lastContext);
401 <RulesPattern>{StartRound} {
402 yyextra->roundCount++;
403 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
404 yyextra->lastContext = YY_START;
407 <RulesRound>{RulesCurly} {
408 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
410 <RulesRound>{StartSquare} {
411 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
412 BEGIN(RulesRoundSquare);
414 <RulesRound>{StartDouble} {
415 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
416 BEGIN(RulesRoundDouble);
418 <RulesRound>{EscapeRulesChar} {
419 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
422 yyextra->roundCount++;
423 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
426 yyextra->roundCount--;
427 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
428 if (!yyextra->roundCount) BEGIN( yyextra->lastContext ) ;
431 yyextra->cCodeBuffer += "\n";
434 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
437 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
439 <RulesPattern>{ws}+"|" {
440 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
441 yyextra->curlyCount = 0;
444 <RulesPattern>^{ws}*{nl} {
445 yyextra->cCodeBuffer += "\n";
447 <RulesPattern>^{ws}+ {
450 <RulesPattern>({ws}|{nl}) {
452 yyextra->curlyCount = 0;
455 <RulesPattern>"\\\\" {
456 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
458 <RulesPattern>{CCS} {
459 yyextra->cCodeBuffer += yytext;
460 yyextra->lastContext = YY_START;
464 yyextra->cCodeBuffer += repeatChar(' ', yyleng);
466 <SkipCurly>{B}*"#"{B}+[0-9]+{B}+/"\"" { /* line control directive */
467 yyextra->cCodeBuffer += yytext;
468 yyextra->lastPreLineCtrlContext = YY_START;
469 BEGIN( PreLineCtrl );
471 <PreLineCtrl>"\""[^\n\"]*"\"" {
472 yyextra->cCodeBuffer += yytext;
475 yyextra->cCodeBuffer += yytext;
478 yyextra->cCodeBuffer += yytext;
479 BEGIN( yyextra->lastPreLineCtrlContext );
482 yyextra->cCodeBuffer += yytext;
483 ++yyextra->curlyCount ;
485 <SkipCurly>"}"/{BN}*{DCOMM}"<!--" | /* see bug710917 */
487 yyextra->cCodeBuffer += yytext;
488 if( yyextra->curlyCount )
490 --yyextra->curlyCount ;
493 <SkipCurly>"}"{BN}*{DCOMM}"<" {
494 yyextra->cCodeBuffer += yytext;
495 if ( yyextra->curlyCount )
497 --yyextra->curlyCount ;
501 yyextra->docBlockContext = SkipCurlyEndDoc;
502 if (yytext[yyleng-3]=='/')
513 yyextra->cCodeBuffer += yytext;
514 yyextra->lastStringContext=SkipCurly;
517 <SkipCurly>^{B}*"#" {
518 yyextra->cCodeBuffer += yytext;
519 yyextra->lastPreLineCtrlContext = YY_START;
520 BEGIN( PreLineCtrl );
522 <SkipCurly>{B}*{RAWBEGIN} {
523 QCString raw=QCString(yytext).stripWhiteSpace();
524 yyextra->delimiter = raw.mid(2);
525 yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
526 yyextra->lastRawStringContext = YY_START;
527 yyextra->cCodeBuffer += yytext;
530 <SkipCurly>[^\n#"'@\\/{}<]+ {
531 yyextra->cCodeBuffer += yytext;
534 yyextra->cCodeBuffer += yytext;
535 yyextra->lastCContext = YY_START;
539 yyextra->cCodeBuffer += yytext;
540 yyextra->lastCContext = YY_START;
541 BEGIN(SkipCxxComment);
543 <SkipCurly>{CHARLIT} {
544 yyextra->cCodeBuffer += yytext;
547 yyextra->cCodeBuffer += yytext;
550 yyextra->cCodeBuffer += yytext;
552 <SkipCurly>({CPPC}{B}*)?{CCS}"!" {
553 yyextra->cCodeBuffer += yytext;
554 yyextra->docBlockContext = YY_START;
557 <SkipCurly>{CCS}"*"[*]+{BL} {
558 bool javadocBanner = Config_getBool(JAVADOC_BANNER);
559 yyextra->cCodeBuffer += yytext;
562 yyextra->docBlockContext = YY_START;
570 <SkipCurly>({CPPC}{B}*)?{CCS}"*"/{NCOMM} {
571 yyextra->cCodeBuffer += yytext;
572 yyextra->docBlockContext = YY_START;
575 <SkipCurly>{CPPC}"!" {
576 yyextra->cCodeBuffer += yytext;
577 yyextra->docBlockContext = YY_START;
580 <SkipCurly>{CPPC}"/"/[^/] {
581 yyextra->cCodeBuffer += yytext;
582 yyextra->docBlockContext = YY_START;
587 yyextra->cCodeBuffer += yytext;
588 if (yyextra->curlyCount<=0)
594 yyextra->cCodeBuffer += yytext;
597 yyextra->cCodeBuffer += yytext;
598 BEGIN( yyextra->lastStringContext );
600 <SkipString>{CCS}|{CCE}|{CPPC} {
601 yyextra->cCodeBuffer += yytext;
604 yyextra->cCodeBuffer += yytext;
607 yyextra->cCodeBuffer += yytext;
609 <SkipCxxComment>.*"\\\n" { // line continuation
610 yyextra->cCodeBuffer += yytext;
612 <SkipCxxComment>{ANYopt}/\n {
613 yyextra->cCodeBuffer += yytext;
614 BEGIN( yyextra->lastCContext ) ;
617 yyextra->cCodeBuffer += yytext ;
619 <Comment>{CCS} { yyextra->cCodeBuffer += yytext ; }
620 <Comment>{CPPC} { yyextra->cCodeBuffer += yytext ; }
621 <Comment>{CMD}("code"|"verbatim") {
622 yyextra->insideCode=TRUE;
623 yyextra->cCodeBuffer += yytext ;
625 <Comment>{CMD}("endcode"|"endverbatim") {
626 yyextra->insideCode=FALSE;
627 yyextra->cCodeBuffer += yytext ;
629 <Comment>[^ \.\t\r\n\/\*]+ { yyextra->cCodeBuffer += yytext ; }
630 <Comment>{CCE} { yyextra->cCodeBuffer += yytext ;
631 if (!yyextra->insideCode) BEGIN( yyextra->lastContext ) ;
633 <Comment>. { yyextra->cCodeBuffer += *yytext ; }
635 <SkipComment>{CPPC}|{CCS} {
636 yyextra->cCodeBuffer += yytext;
638 <SkipComment>[^\*\n]+ {
639 yyextra->cCodeBuffer += yytext;
642 yyextra->cCodeBuffer += yytext;
644 <SkipComment>{B}*{CCE} {
645 yyextra->cCodeBuffer += yytext;
646 BEGIN( yyextra->lastCContext );
649 yyextra->cCodeBuffer += yytext;
651 <RawString>{RAWEND} {
652 yyextra->cCodeBuffer += yytext;
653 QCString delimiter = yytext+1;
654 delimiter=delimiter.left(delimiter.length()-1);
655 if (delimiter==yyextra->delimiter)
657 BEGIN(yyextra->lastRawStringContext);
661 yyextra->cCodeBuffer += yytext;
664 yyextra->cCodeBuffer += yytext;
667 yyextra->cCodeBuffer += yytext;
671 /* ---- Single line comments ------ */
672 <DocLine>[^\n]*"\n"[ \t]*{CPPC}[/!][<]? { // continuation of multiline C++-style comment
673 yyextra->cCodeBuffer += yytext;
675 <DocLine>{B}*{CPPC}"/"[/]+{Bopt}/"\n" { // ignore marker line (see bug700345)
676 yyextra->cCodeBuffer += yytext;
677 BEGIN( yyextra->docBlockContext );
679 <DocLine>{NONLopt}/"\n"{B}*{CPPC}[!/]{B}*{CMD}"}" { // next line is an end group marker, see bug 752712
680 yyextra->cCodeBuffer += yytext;
681 BEGIN( yyextra->docBlockContext );
683 <DocLine>{NONLopt}/"\n" { // whole line
684 yyextra->cCodeBuffer += yytext;
685 BEGIN( yyextra->docBlockContext );
688 /* ---- Comments blocks ------ */
690 <DocBlock>"*"*{CCE} { // end of comment block
691 yyextra->cCodeBuffer += yytext;
692 BEGIN(yyextra->docBlockContext);
694 <DocBlock>^{B}*"*"+/[^/] {
695 yyextra->cCodeBuffer += yytext;
697 <DocBlock>^{B}*({CPPC})?{B}*"*"+/[^/a-z_A-Z0-9*] { // start of a comment line
698 yyextra->cCodeBuffer += yytext;
700 <DocBlock>^{B}*({CPPC}){B}* { // strip embedded C++ comments if at the start of a line
701 yyextra->cCodeBuffer += yytext;
703 <DocBlock>{CPPC} { // slashes in the middle of a comment block
704 yyextra->cCodeBuffer += yytext;
706 <DocBlock>{CCS} { // start of a new comment in the
707 // middle of a comment block
708 yyextra->cCodeBuffer += yytext;
710 <DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
711 yyextra->cCodeBuffer += yytext;
713 <DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
714 yyextra->cCodeBuffer += yytext;
715 yyextra->docBlockName=&yytext[1];
716 if (yyextra->docBlockName.at(1)=='[')
718 yyextra->docBlockName.at(1)=']';
720 if (yyextra->docBlockName.at(1)=='{')
722 yyextra->docBlockName.at(1)='}';
724 if (yyextra->docBlockName.at(1)=='(')
726 yyextra->docBlockName.at(1)=')';
728 yyextra->fencedSize=0;
729 yyextra->nestedComment=FALSE;
732 <DocBlock>{B}*"<"{PRE}">" {
733 yyextra->cCodeBuffer += yytext;
734 yyextra->docBlockName="<pre>";
735 yyextra->fencedSize=0;
736 yyextra->nestedComment=FALSE;
739 <DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim type command (which could contain nested comments!)
740 yyextra->cCodeBuffer += yytext;
741 yyextra->docBlockName="uml";
742 yyextra->fencedSize=0;
743 yyextra->nestedComment=FALSE;
746 <DocBlock>{CMD}("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command (which could contain nested comments!)
747 yyextra->cCodeBuffer += yytext;
748 yyextra->docBlockName=&yytext[1];
749 yyextra->fencedSize=0;
750 yyextra->nestedComment=FALSE;
753 <DocBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
754 yyextra->cCodeBuffer += yytext;
755 QCString pat = substitute(yytext,"*"," ");
756 yyextra->docBlockName="~~~";
757 yyextra->fencedSize=pat.stripWhiteSpace().length();
758 yyextra->nestedComment=FALSE;
761 <DocBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
762 yyextra->cCodeBuffer += yytext;
763 QCString pat = substitute(yytext,"*"," ");
764 yyextra->docBlockName="```";
765 yyextra->fencedSize=pat.stripWhiteSpace().length();
766 yyextra->nestedComment=FALSE;
769 <DocBlock>{B}*"<code>" {
772 <DocBlock>[^@*~\/\\\n]+ { // any character that isn't special
773 yyextra->cCodeBuffer += yytext;
775 <DocBlock>\n { // newline
776 yyextra->cCodeBuffer += yytext;
778 <DocBlock>. { // command block
779 yyextra->cCodeBuffer += yytext;
781 /* ---- Copy verbatim sections ------ */
783 <DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
784 yyextra->cCodeBuffer += yytext;
785 if (yyextra->docBlockName=="<pre>")
790 <DocCopyBlock>"</"{CODE}">" { // end of a <code> block
791 yyextra->cCodeBuffer += yytext;
792 if (yyextra->docBlockName=="<code>")
797 <DocCopyBlock>[\\@]("f$"|"f]"|"f}"|"f)") {
798 yyextra->cCodeBuffer += yytext;
799 if (yyextra->docBlockName==&yytext[1])
804 <DocCopyBlock>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
805 yyextra->cCodeBuffer += yytext;
806 if (yyextra->docBlockName==&yytext[4])
811 <DocCopyBlock>^{B}*"*"+/{BN}+ { // start of a comment line
812 yyextra->cCodeBuffer += yytext;
813 if (yyextra->docBlockName=="verbatim")
817 else if (yyextra->docBlockName=="code")
823 yyextra->cCodeBuffer += yytext;
826 <DocCopyBlock>^{B}*"*"+/{B}+"*"{BN}* { // start of a comment line with two *'s
827 if (yyextra->docBlockName=="code")
829 yyextra->cCodeBuffer += yytext;
836 <DocCopyBlock>^{B}*"*"+/({ID}|"(") { // Assume *var or *(... is part of source code (see bug723516)
837 if (yyextra->docBlockName=="code")
839 yyextra->cCodeBuffer += yytext;
846 <DocCopyBlock>^{B}*"*"+/{BN}* { // start of a comment line with one *
847 if (yyextra->docBlockName=="code")
849 if (yyextra->nestedComment) // keep * it is part of the code
851 yyextra->cCodeBuffer += yytext;
853 else // remove * it is part of the comment block
855 yyextra->cCodeBuffer += yytext;
863 <DocCopyBlock>^({B}*"*"+)?{B}{0,3}"~~~"[~]* {
864 yyextra->cCodeBuffer += yytext;
865 QCString pat = substitute(yytext,"*"," ");
866 if (yyextra->fencedSize==pat.stripWhiteSpace().length())
871 <DocCopyBlock>^({B}*"*"+)?{B}{0,3}"```"[`]* {
872 yyextra->cCodeBuffer += yytext;
873 QCString pat = substitute(yytext,"*"," ");
874 if (yyextra->fencedSize==pat.stripWhiteSpace().length())
879 <DocCopyBlock>[^<@/\*\]~\$\\\n]+ { // any character that is not special
880 yyextra->cCodeBuffer += yytext;
882 <DocCopyBlock>{CCS}|{CCE}|{CPPC} {
885 yyextra->nestedComment=TRUE;
887 else if (yytext[0]=='*')
889 yyextra->nestedComment=FALSE;
891 yyextra->cCodeBuffer += yytext;
893 <DocCopyBlock>\n { // newline
894 yyextra->cCodeBuffer += yytext;
896 <DocCopyBlock>. { // any other character
897 yyextra->cCodeBuffer += yytext;
899 <SkipCurlyEndDoc>"}"{BN}*{DCOMM}"<" { // desc is followed by another one
900 yyextra->docBlockContext = SkipCurlyEndDoc;
901 yyextra->cCodeBuffer += yytext;
902 if (yytext[yyleng-3]=='/')
911 <SkipCurlyEndDoc>"}" {
912 yyextra->cCodeBuffer += yytext;
916 <UserSection>.*{nl} {
917 yyextra->cCodeBuffer += yytext;
922 <*>. { fprintf(stderr,"Lex scanner Def rule for %s: #%s#\n",stateToString(YY_START),yytext);}
923 <*>{nl} { fprintf(stderr,"Lex scanner Def rule for newline %s: #%s#\n",stateToString(YY_START),yytext);}
926 handleCCode(yyscanner);
931 //----------------------------------------------------------------------------
932 static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size)
934 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
936 while( c < max_size && yyextra->inputString[yyextra->inputPosition] )
938 *buf = yyextra->inputString[yyextra->inputPosition++] ;
939 //printf("%d (%c)\n",*buf,*buf);
945 //-----------------------------------------------------------------------------
947 static void parseMain(yyscan_t yyscanner,
948 const QCString &fileName,
950 const std::shared_ptr<Entry> &rt,
951 ClangTUParser *clangParser)
953 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
955 yyextra->inputString = fileBuf;
956 yyextra->inputPosition = 0;
957 lexscannerYYrestart(0,yyscanner);
959 yyextra->current_root = rt;
960 yyextra->yyFileName = fileName;
961 yyextra->clangParser = clangParser;
962 yyextra->language = getLanguageFromFileName(yyextra->yyFileName);
963 rt->lang = yyextra->language;
964 msg("Parsing file %s...\n",qPrint(yyextra->yyFileName));
966 yyextra->current_root = rt;
967 yyextra->current = std::make_shared<Entry>();
968 int sec=guessSection(yyextra->yyFileName);
971 yyextra->current->name = yyextra->yyFileName;
972 yyextra->current->section = sec;
973 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
975 yyextra->current->reset();
978 lexscannerYYlex(yyscanner);
980 rt->program.str(std::string());
983 //----------------------------------------------------------------------------
986 static void handleCCode(yyscan_t yyscanner)
988 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
990 if (yyextra->cCodeBuffer.isEmpty()) return;
991 yyextra->cOutlineParser.parseInput(yyextra->yyFileName,
992 yyextra->cCodeBuffer.data(),
993 yyextra->current_root,
994 yyextra->clangParser);
995 yyextra->cCodeBuffer.resize(0);
998 //----------------------------------------------------------------------------
1000 struct LexOutlineParser::Private
1003 lexscannerYY_state state;
1006 LexOutlineParser::LexOutlineParser() : p(std::make_unique<LexOutlineParser::Private>())
1008 lexscannerYYlex_init_extra(&p->state,&p->yyscanner);
1010 lexscannerYYset_debug(1,p->yyscanner);
1014 LexOutlineParser::~LexOutlineParser()
1016 lexscannerYYlex_destroy(p->yyscanner);
1019 void LexOutlineParser::parseInput(const QCString &fileName,
1020 const char *fileBuf,
1021 const std::shared_ptr<Entry> &root,
1022 ClangTUParser *clangParser)
1024 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
1026 printlex(yy_flex_debug, TRUE, __FILE__, qPrint(fileName));
1028 ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
1030 printlex(yy_flex_debug, FALSE, __FILE__, qPrint(fileName));
1034 //----------------------------------------------------------------------------
1036 #if USE_STATE2STRING
1037 #include "lexscanner.l.h"