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