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