383 {BS}[&]*{BS}!.*\n {
384 yyextra->lineCountPrepass ++;
385 }
386<Prepass>^{BS}\n { /* skip empty lines */
387 yyextra->lineCountPrepass ++;
388 }
389<*>^.*\n { // prepass: look for line continuations
390 yyextra->functionLine =
FALSE;
391
392 DBG_CTX((stderr,
"---%s", yytext));
393
396 if (indexEnd>=0 && yytext[indexEnd]!='&')
397 {
398 indexEnd=-1;
399 }
static int getAmpersandAtTheStart(const char *buf, int length)
400
401 if (indexEnd<0)
402 {
403 if (YY_START == Prepass)
404 {
405
406
407 yyextra->inputStringPrepass+=(const char*)(yytext+(indexStart+1));
408
409
410 pushBuffer(yyscanner,yyextra->inputStringPrepass);
411 yyextra->colNr = 0;
413 }
414 else
415 {
416 yyextra->colNr = 0;
417 REJECT;
418 }
419 }
420 else
421 {
422 if (YY_START != Prepass)
423 {
424 yyextra->comments.clear();
425 yyextra->inputStringPrepass=
QCString();
426 yy_push_state(Prepass,yyscanner);
427 }
static void pop_state(yyscan_t yyscanner)
static void pushBuffer(yyscan_t yyscanner, const QCString &buffer)
428
429 size_t length = yyextra->inputStringPrepass.length();
430
431
432 yyextra->inputStringPrepass+=(const char*)(yytext+(indexStart+1));
433 yyextra->lineCountPrepass ++;
434
435
436 truncatePrepass(yyscanner,
static_cast<int>(length) + indexEnd - indexStart - 1);
437 }
438 }
static void truncatePrepass(yyscan_t yyscanner, int index)
439
440
441
442<String>\"|\' { // string ends with next quote without previous backspace
443 if (yytext[0]!=yyextra->stringStartSymbol)
444 {
445 yyextra->colNr -= (int)yyleng;
446 REJECT;
447 }
448 if (yy_top_state(yyscanner) == Initialization ||
449 yy_top_state(yyscanner) == ArrayInitializer)
450 {
451 yyextra->initializer+=yytext;
452 }
454 }
455<String>[\x80-\xFF]* |
456<String>. { if (yy_top_state(yyscanner) == Initialization ||
457 yy_top_state(yyscanner) == ArrayInitializer)
458 {
459 yyextra->initializer+=yytext;
460 }
461 }
462<*>\"|\' { /* string starts */
463 if (YY_START == StrIgnore)
464 { yyextra->colNr -= (int)yyleng;
465 REJECT;
466 };
467 yy_push_state(YY_START,yyscanner);
468 if (yy_top_state(yyscanner) == Initialization ||
469 yy_top_state(yyscanner) == ArrayInitializer)
470 {
471 yyextra->initializer+=yytext;
472 }
473 yyextra->stringStartSymbol=yytext[0];
474 BEGIN(String);
475 }
476
477
478
479<*>"!"/([^<>\n]|"<ff>"|"<FF>") { if (YY_START == String || YY_START == DocCopyBlock)
480 { yyextra->colNr -= (int)yyleng;
481 REJECT;
482 }
483
484
485 if ((YY_START != StrIgnore) && (YY_START != String))
486 {
487 yy_push_state(YY_START,yyscanner);
488 BEGIN(StrIgnore);
489 yyextra->debugStr="*!";
490 DBG_CTX((stderr,
"start comment %d\n",yyextra->lineNr));
491 }
492 }
493<StrIgnore>.?/\n { pop_state(yyscanner); // comment ends with endline character
494 DBG_CTX((stderr,
"end comment %d %s\n",yyextra->lineNr,
qPrint(yyextra->debugStr)));
495 }
496<StrIgnore>[\x80-\xFF]* |
497<StrIgnore>. { yyextra->debugStr+=yytext; }
498
499
500
501
502<Start,ModuleBody,SubprogBody>"use"{BS_} {
503 if (YY_START == Start)
504 {
507 yy_push_state(ModuleBody,yyscanner);
508 }
509 yy_push_state(Use,yyscanner);
510 }
511<Use>{ID} {
512 DBG_CTX((stderr,
"using dir %s\n",yytext));
513 yyextra->current->name=yytext;
514 yyextra->current->name=yyextra->current->name.lower();
515 yyextra->current->fileName = yyextra->fileName;
516 yyextra->current->section=EntryType::makeUsingDir();
517 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
518 yyextra->current->lang = SrcLangExt::Fortran;
520 }
521<Use>{ID}/, {
522 yyextra->useModuleName=yytext;
523 yyextra->useModuleName=yyextra->useModuleName.lower();
524 }
525<Use>,{BS}"ONLY" { BEGIN(UseOnly);
526 }
527<UseOnly>{BS},{BS} {}
528<UseOnly>{ID} {
529 yyextra->current->name= yyextra->useModuleName+"::"+yytext;
530 yyextra->current->name=yyextra->current->name.lower();
531 yyextra->current->fileName = yyextra->fileName;
532 yyextra->current->section=EntryType::makeUsingDecl();
533 yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
534 yyextra->current->lang = SrcLangExt::Fortran;
535 }
536<Use,UseOnly>"\n" {
537 yyextra->colNr -= 1;
538 unput(*yytext);
540 }
541
542
543<Start,ModuleBody,SubprogBody>{
544^{BS}interface{IDSYM}+ { /* variable with interface prefix */ }
545^{BS}interface { yyextra->ifType = IF_SPECIFIC;
546 yy_push_state(InterfaceBody,yyscanner);
547
548
549 }
550
551^{BS}abstract{BS_}interface { yyextra->ifType = IF_ABSTRACT;
552 yy_push_state(InterfaceBody,yyscanner);
553
554
555 }
556
557^{BS}interface{BS_}{ID}{ARGS}? { yyextra->ifType = IF_GENERIC;
558 yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1;
559 yy_push_state(InterfaceBody,yyscanner);
560
561
565 startScope(yyscanner,yyextra->last_entry.get());
566 }
static void addInterface(yyscan_t yyscanner, QCString name, InterfaceType type)
567}
568
569<InterfaceBody>^{BS}end{BS}interface({BS_}{ID})? {
570
572 {
573 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr - 1;
574 }
576 {
578 }
581 }
static void endScope(yyscan_t yyscanner)
end scope
582<InterfaceBody>module{BS}procedure { yy_push_state(YY_START,yyscanner);
583 BEGIN(ModuleProcedure);
584 }
585<ModuleProcedure>{ID} { QCString name = QCString(yytext).lower();
587 {
589 startScope(yyscanner,yyextra->last_entry.get());
590 }
591
592 yyextra->current->section = EntryType::makeFunction();
593 yyextra->current->name = name;
594 yyextra->moduleProcedures.push_back(yyextra->current);
596 }
597<ModuleProcedure>"\n" { yyextra->colNr -= 1;
598 unput(*yytext);
600 }
601<InterfaceBody>. {}
602
603
604<Start>^{BS}{CONTAINS}/({BS}|\n|!|;) {
605 if (YY_START == Start)
606 {
608 yy_push_state(ModuleBodyContains,yyscanner);
609 }
610 }
611<ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(ModuleBodyContains); }
612<SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(SubprogBodyContains); }
613<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!|;) { BEGIN(TypedefBodyContains); }
614
615
616<Start>block{BS}data{BS}{ID_} { //
618 yy_push_state(BlockData,yyscanner);
619 yyextra->defaultProtection = Protection::Public;
620 }
621<Start>module|program{BS_} { //
623 if (yytext[0]=='m' || yytext[0]=='M')
624 {
625 yy_push_state(
Module,yyscanner);
626 }
627 else
628 {
629 yy_push_state(Program,yyscanner);
630 }
631 yyextra->defaultProtection = Protection::Public;
632 }
633<BlockData>^{BS}"end"({BS}(block{BS}data)({BS_}{ID})?)?{BS}/(\n|!|;) { // end block data
634
635
636 yyextra->defaultProtection = Protection::Public;
638 }
639<Start,ModuleBody,ModuleBodyContains>"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!|;) { // end module
641 if (!
endScope(yyscanner,yyextra->current_root))
642 {
644 }
645 yyextra->defaultProtection = Protection::Public;
646 if (yyextra->global_scope)
647 {
649 {
650 yy_push_state(Start,yyscanner);
651 }
652 else
653 {
655 }
656 }
657 else
658 {
659 yy_push_state(Start,yyscanner);
661 }
663 }
static void resolveModuleProcedures(yyscan_t yyscanner, Entry *current_root)
fill empty interface module procedures with info from corresponding module subprogs
static void popBlockState(yyscan_t yyscanner)
664<Module>{ID} {
667 BEGIN(ModuleBody);
668 }
669<Program>{ID} {
672 BEGIN(ModuleBody);
673 }
674
675
676
677<ModuleBody,TypedefBody,TypedefBodyContains>private/{BS}(\n|"!") {
678 yyextra->defaultProtection = Protection::Private;
679 yyextra->current->protection = yyextra->defaultProtection ;
680 }
681<ModuleBody,TypedefBody,TypedefBodyContains>public/{BS}(\n|"!") {
682 yyextra->defaultProtection = Protection::Public;
683 yyextra->current->protection = yyextra->defaultProtection ;
684 }
685
686
687
688<ModuleBody>^{BS}type{BS}"=" {}
689<Start,ModuleBody>^{BS}type/[^a-z0-9_] {
690 if (YY_START == Start)
691 {
694 yy_push_state(ModuleBody,yyscanner);
695 }
696
697 yy_push_state(
Typedef,yyscanner);
698 yyextra->current->protection = Protection::Package;
699 yyextra->typeProtection = Protection::Public;
700 yyextra->typeMode = true;
701 }
702<Typedef>{
703{COMMA} {}
704
705{BS}"::"{BS} {}
706
707abstract {
708 yyextra->current->spec.setAbstractClass(true);
709 }
710extends{ARGS} {
712 yyextra->current->extends.emplace_back(basename, Protection::Public, Specifier::Normal);
713 }
714public {
715 yyextra->current->protection = Protection::Public;
716 }
717private {
718 yyextra->current->protection = Protection::Private;
719 }
720{LANGUAGE_BIND_SPEC} {
721
722 }
723{ID} { /* type name found */
724 yyextra->current->section = EntryType::makeClass();
725 yyextra->current->spec.setStruct(true);
726 yyextra->current->name = yytext;
727 yyextra->current->fileName = yyextra->fileName;
728 yyextra->current->bodyLine = yyextra->lineNr;
729 yyextra->current->startLine = yyextra->lineNr;
730
731
732 if (yyextra->current_root &&
733 (yyextra->current_root->section.isClass() ||
734 yyextra->current_root->section.isNamespace()))
735 {
736 yyextra->current->name = yyextra->current_root->name + "::" + yyextra->current->name;
737 }
738
739
740 if( yyextra->current->protection == Protection::Package )
741 {
742 yyextra->current->protection = yyextra->defaultProtection;
743 }
744 else if( yyextra->current->protection == Protection::Public )
745 {
746 yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower().str()] |=
QCString(
"public");
747 }
748 else if( yyextra->current->protection == Protection::Private )
749 {
750 yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower().str()] |=
QCString(
"private");
751 }
752
754 startScope(yyscanner,yyextra->last_entry.get());
755 BEGIN(TypedefBody);
756 }
757}
758
759<TypedefBodyContains>{ /* Type Bound Procedures */
760^{BS}PROCEDURE{ARGS}? {
762 }
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
763^{BS}final {
764 yyextra->current->spec.setFinal(true);
766 }
767^{BS}generic {
769 }
770{COMMA} {
771 }
772{ATTR_SPEC} {
774 }
775{BS}"::"{BS} {
776 }
777{ID} {
779 yyextra->modifiers[yyextra->current_root][name.
lower().
str()] |= yyextra->currentModifiers;
780 yyextra->current->section = EntryType::makeFunction();
781 yyextra->current->name = name;
782
783 if (yyextra->current->type.find('(') != -1)
784 {
786 }
787 else
788 {
789 yyextra->current->args = name.
lower();
790 }
791 yyextra->current->fileName = yyextra->fileName;
792 yyextra->current->bodyLine = yyextra->lineNr;
793 yyextra->current->startLine = yyextra->lineNr;
795 }
796{BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */
798 int i = tmp.
find(
"=>");
799 if (i!=-1)
800 {
802 }
804 if (yyextra->last_entry->type == "generic")
805 {
806
807
808
810 while (i>0)
811 {
812 copyEntry(yyextra->current, yyextra->last_entry);
813 yyextra->current->name = yyextra->last_entry->name;
814 yyextra->current->section = EntryType::makeFunction();
816
820 }
821 }
822
823 yyextra->last_entry->args = tmp;
824 }
QCString left(size_t len) const
825"\n" {
828 yyextra->docBlock.clear();
829 }
static void newLine(yyscan_t yyscanner)
Holds yyextra->modifiers (ie attributes) for one symbol (variable, function, etc).
830}
831
832
833<TypedefBody,TypedefBodyContains>{
834^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!|;) { /* end type definition */
835 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
836 if (!
endScope(yyscanner,yyextra->current_root))
837 {
839 }
840 yyextra->typeMode = false;
842 }
843^{BS}"end"{BS}/(\n|!|;) { /* incorrect end type definition */
844 warn(yyextra->fileName,yyextra->lineNr,
"Found 'END' instead of 'END TYPE'");
845 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
846 if (!
endScope(yyscanner,yyextra->current_root))
847 {
849 }
850 yyextra->typeMode = false;
852 }
853}
854
855
856
857<SubprogBody,SubprogBodyContains>^{BS}[0-9]*{BS}"end"({BS}{SUBPROG}({BS_}{ID})?)?{BS}/(\n|!|;) {
858
859
860
861
862
864 {
865 endScope(yyscanner,yyextra->current_root);
866 yyextra->last_entry->endBodyLine = yyextra->lineNr - 1;
867 }
868 yyextra->current_root->endBodyLine = yyextra->lineNr - 1;
869
870 if (!
endScope(yyscanner,yyextra->current_root))
871 {
873 }
874 yyextra->subrCurrent.pop_back();
878 }
879<BlockData>{
880{ID} {
881 }
882}
883<Start,ModuleBody,TypedefBody,SubprogBody,FEnum>{
884^{BS}{TYPE_SPEC}/{SEPARATE} {
885 yyextra->last_enum.reset();
886 if (YY_START == FEnum)
887 {
888 yyextra->argType = "@";
889 }
890 else
891 {
893 }
894 yyextra->current->bodyLine = yyextra->lineNr + 1;
895 yyextra->current->endBodyLine = yyextra->lineNr + yyextra->lineCountPrepass;
896
897 if (YY_START == Start)
898 {
901 yy_push_state(ModuleBody,yyscanner);
902 }
903 yy_push_state(AttributeList,yyscanner);
904 }
905{EXTERNAL_STMT}/({BS}"::"|{BS_}{ID}) {
906
907 if (YY_START == Start)
908 {
911 yy_push_state(ModuleBody,yyscanner);
912 }
916 yy_push_state(AttributeList,yyscanner);
917 }
918{ATTR_STMT}/{BS_}{ID} |
919{ATTR_STMT}/{BS}"::" {
920
921 DBG_CTX((stderr,
"5=========> Attribute statement: %s\n", yytext));
922 if (YY_START == Start)
923 {
926 yy_push_state(ModuleBody,yyscanner);
927 }
930 yyextra->argType="";
931 yy_push_state(YY_START,yyscanner);
932 BEGIN( AttributeList ) ;
933 }
934"common" {
935 if (YY_START == Start)
936 {
939 yy_push_state(ModuleBody,yyscanner);
940 }
941 }
942{ID} {
944 {
947 yy_push_state(ModuleBody,yyscanner);
948 }
949 }
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
950^{BS}"type"{BS_}"is"/{BT_} {}
951^{BS}"type"{BS}"=" {}
952^{BS}"class"{BS_}"is"/{BT_} {}
953^{BS}"class"{BS_}"default" {}
954}
955<AttributeList>{
956{COMMA} {}
957{BS} {}
958{LANGUAGE_BIND_SPEC} {
959 yyextra->currentModifiers |= yytext;
960 }
961{ATTR_SPEC}. { /* update yyextra->current yyextra->modifiers when it is an ATTR_SPEC and not a variable name */
962
963 char chr = yytext[(int)yyleng-1];
965 {
966 yyextra->colNr -= (int)yyleng;
967 REJECT;
968 }
969 else
970 {
973 yyextra->colNr -= 1;
974 unput(yytext[(int)yyleng-1]);
975 yyextra->currentModifiers |= (tmp);
976 }
977 }
978"::" { /* end attribute list */
979 BEGIN( FVariable );
980 }
981. { /* unknown attribute, consider variable name */
982
983 yyextra->colNr -= 1;
984 unput(*yytext);
985 BEGIN( FVariable );
986 }
987}
988
989<FVariable>{BS} {}
990<FVariable>{OPERATOR_ID} { /* parse operator access statements "public :: operator(==)" */
992
993
994 int currentState = YY_START;
996 int outerState = YY_START;
997 yy_push_state(currentState,yyscanner);
998 if( outerState == Start || outerState == ModuleBody )
999 {
1000 if ((yyextra->current_root) &&
1001 (yyextra->current_root->section.isClass() ||
1002 yyextra->current_root->section.isNamespace()))
1003 {
1004 name = yyextra->current_root->name + "::" + name;
1005 }
1006 }
1007
1008 yyextra->modifiers[yyextra->current_root][name.
str()] |= yyextra->currentModifiers;
1009 }
1010<FVariable>{ID} { /* parse variable declaration */
1011
1012
1014 name = name.
lower();
1015
1016 if ((yyextra->current_root) && yyextra->current_root->section.isNamespace())
1017 {
1018 name = yyextra->current_root->name + "::" + name;
1019 }
1020
1021 yyextra->modifiers[yyextra->current_root][name.
lower().
str()] |= yyextra->currentModifiers;
1022 yyextra->argName= name;
1023
1025 if (!yyextra->argType.isEmpty() && !yyextra->current_root->section.isFunction())
1026 {
1028 yyextra->current->section = EntryType::makeVariable();
1029 yyextra->current->name = yyextra->argName;
1030 yyextra->current->type = yyextra->argType;
1031 yyextra->current->fileName = yyextra->fileName;
1032 yyextra->current->bodyLine = yyextra->lineNr;
1033 yyextra->current->startLine = yyextra->lineNr;
1034 if (yyextra->argType == "@")
1035 {
1036 yyextra->current_root->copyToSubEntry(yyextra->current);
1037
1038 yyextra->last_enum = yyextra->current;
1039 yyextra->current_root->parent()->moveToSubEntryAndRefresh(yyextra->current);
1041 }
1042 else
1043 {
1045 }
1046 }
1047 else if (!yyextra->argType.isEmpty())
1048 {
1050 if (parameter)
1051 {
1054 if (!yyextra->docBlock.isEmpty())
1055 {
1057 }
1058 }
1059
1060 if (parameter)
1061 {
1062 yyextra->modifiers[yyextra->current_root][name.
lower().
str()].type = yyextra->argType;
1063 }
1064 else
1065 {
1066 if ((yyextra->current_root->name.lower() == yyextra->argName.lower()) ||
1067 (yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower().str()].returnName.lower() == yyextra->argName.lower()))
1068 {
1069 int strt = yyextra->current_root->type.find("function");
1072 if (strt != -1)
1073 {
1075 lft = "";
1076 rght = "";
1078 if ((yyextra->current_root->type.length() - strt - strlen("function"))!= 0)
1079 {
1080 rght = yyextra->current_root->type.
right(yyextra->current_root->type.length() - strt - (
int)strlen(
"function")).
stripWhiteSpace();
1081 }
1082 yyextra->current_root->type = lft;
1084 {
1085 if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " ";
1086 yyextra->current_root->type += rght;
1087 }
1088 if (yyextra->argType.stripWhiteSpace().length() > 0)
1089 {
1090 if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " ";
1091 yyextra->current_root->type += yyextra->argType.stripWhiteSpace();
1092 }
1093 if (yyextra->current_root->type.length() > 0) yyextra->current_root->type += " ";
1094 yyextra->current_root->type += "function";
1095 if (!yyextra->docBlock.isEmpty())
1096 {
1098 }
1099 }
1100 else
1101 {
1102 yyextra->current_root->type += " " + yyextra->argType.stripWhiteSpace();
1103 }
1104 yyextra->current_root->type = yyextra->current_root->type.
stripWhiteSpace();
1105 yyextra->modifiers[yyextra->current_root][name.
lower().
str()].type = yyextra->current_root->type;
1106 }
1107 else
1108 {
1109 yyextra->modifiers[yyextra->current_root][name.
lower().
str()].type = yyextra->argType;
1110 }
1111 }
1112
1113
1114
1115 yyextra->current->doc.clear();
1116 yyextra->current->brief.clear();
1117 }
1118 }
static void subrHandleCommentBlock(yyscan_t yyscanner, const QCString &doc, bool brief)
Handle parameter description as defined after the declaration of the parameter.
static void subrHandleCommentBlockResult(yyscan_t yyscanner, const QCString &doc, bool brief)
Handle result description as defined after the declaration of the parameter.
1119<FVariable>{ARGS} { /* dimension of the previous entry. */
1122 attr += yytext;
1123 yyextra->modifiers[yyextra->current_root][name.
lower().
str()] |= attr;
1124 }
1125<FVariable>{COMMA} { //printf("COMMA: %d<=..<=%d\n", yyextra->colNr-(int)yyleng, yyextra->colNr);
1126
1128 }
static void updateVariablePrepassComment(yyscan_t yyscanner, int from, int to)
1129<FVariable>{BS}"=" {
1130 yy_push_state(YY_START,yyscanner);
1131 yyextra->initializer="=";
1132 yyextra->initializerScope = yyextra->initializerArrayScope = 0;
1133 BEGIN(Initialization);
1134 }
1135<FVariable>"\n" { yyextra->currentModifiers = SymbolModifiers();
1138 yyextra->docBlock.clear();
1139 }
1140<FVariable>";".*"\n" { yyextra->currentModifiers = SymbolModifiers();
1142 yyextra->docBlock.clear();
1143 yyextra->inputStringSemi =
" \n"+
QCString(yytext+1);
1144 yyextra->lineNr--;
1145 pushBuffer(yyscanner,yyextra->inputStringSemi);
1146 }
1147<*>";".*"\n" {
1148 if (YY_START == FVariable) REJECT;
1149 if (YY_START == String) REJECT;
1150 if (YY_START == StrIgnore) REJECT;
1151 if (YY_START == DocBlock) REJECT;
1152 yyextra->inputStringSemi =
" \n"+
QCString(yytext+1);
1153 yyextra->lineNr--;
1154 pushBuffer(yyscanner,yyextra->inputStringSemi);
1155 }
1156
1157<Initialization,ArrayInitializer>"[" |
1158<Initialization,ArrayInitializer>"(/" { yyextra->initializer+=yytext;
1159 yyextra->initializerArrayScope++;
1160 BEGIN(ArrayInitializer);
1161 }
1162<ArrayInitializer>"]" |
1163<ArrayInitializer>"/)" { yyextra->initializer+=yytext;
1164 yyextra->initializerArrayScope--;
1165 if (yyextra->initializerArrayScope<=0)
1166 {
1167 yyextra->initializerArrayScope = 0;
1168 BEGIN(Initialization);
1169 }
1170 }
1171<ArrayInitializer>. { yyextra->initializer+=yytext; }
1172<Initialization>"(" { yyextra->initializerScope++;
1173 yyextra->initializer+=yytext;
1174 }
1175<Initialization>")" { yyextra->initializerScope--;
1176 yyextra->initializer+=yytext;
1177 }
1178<Initialization>{COMMA} { if (yyextra->initializerScope == 0)
1179 {
1182 if (yyextra->last_enum)
1183 {
1184 yyextra->last_enum->initializer.str(yyextra->initializer.str());
1185 }
1186 else
1187 {
1188 if (yyextra->vtype ==
V_VARIABLE) yyextra->last_entry->initializer.str(yyextra->initializer.str());
1189 }
1190 }
1191 else
1192 {
1193 yyextra->initializer+=", ";
1194 }
1195 }
1196<Initialization>"\n"|"!" { //|
1198 if (yyextra->last_enum)
1199 {
1200 yyextra->last_enum->initializer.str(yyextra->initializer.str());
1201 }
1202 else
1203 {
1204 if (yyextra->vtype ==
V_VARIABLE) yyextra->last_entry->initializer.str(yyextra->initializer.str());
1205 }
1206 yyextra->colNr -= 1;
1207 unput(*yytext);
1208 }
1209<Initialization>. { yyextra->initializer+=yytext; }
1210
1211<*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} {
1212 if (YY_START == Start)
1213 {
1216 yy_push_state(ModuleBody,yyscanner);
1217 }
1218
1219 yy_push_state(FEnum,yyscanner);
1220 yyextra->current->protection = yyextra->defaultProtection;
1221 yyextra->typeProtection = yyextra->defaultProtection;
1222 yyextra->typeMode = true;
1223
1224 yyextra->current->spec.setStruct(true);
1225 yyextra->current->name.clear();
1226 yyextra->current->args.clear();
1227 yyextra->current->name.sprintf("@%d",yyextra->anonCount++);
1228
1229 yyextra->current->section = EntryType::makeEnum();
1230 yyextra->current->fileName = yyextra->fileName;
1231 yyextra->current->startLine = yyextra->lineNr;
1232 yyextra->current->bodyLine = yyextra->lineNr;
1233 if ((yyextra->current_root) &&
1234 (yyextra->current_root->section.isClass() ||
1235 yyextra->current_root->section.isNamespace()))
1236 {
1237 yyextra->current->name = yyextra->current_root->name + "::" + yyextra->current->name;
1238 }
1239
1241 startScope(yyscanner,yyextra->last_entry.get());
1242 BEGIN( FEnum ) ;
1243 }
1244<FEnum>"end"{BS}"enum" {
1245 yyextra->last_entry->parent()->endBodyLine = yyextra->lineNr;
1246 if (!
endScope(yyscanner,yyextra->current_root))
1247 {
1249 }
1250 yyextra->typeMode = false;
1252 }
1253
1254
1255
1256<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}({PREFIX}{BS_})?/{SUBPROG}{BS_} {
1258 {
1259 addInterface(yyscanner,
"$interface$", yyextra->ifType);
1260 startScope(yyscanner,yyextra->last_entry.get());
1261 }
1262
1263
1265 yy_push_state(SubprogPrefix,yyscanner);
1266 }
1267
1268<SubprogPrefix>{BS}{SUBPROG}{BS_} {
1269
1274 BEGIN(Subprog);
1275 yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1;
1276 yyextra->current->startLine = yyextra->lineNr;
1277 }
static void addSubprogram(yyscan_t yyscanner, const QCString &text)
1278
1279<Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{SUBPROG}{BS_} {
1280
1283 {
1284 addInterface(yyscanner,
"$interface$", yyextra->ifType);
1285 startScope(yyscanner,yyextra->last_entry.get());
1286 }
1287
1290 yy_push_state(Subprog,yyscanner);
1291 yyextra->current->bodyLine = yyextra->lineNr + yyextra->lineCountPrepass + 1;
1292 yyextra->current->startLine = yyextra->lineNr;
1293 }
1294
1295<Subprog>{BS} { /* ignore white space */ }
1296<Subprog>{ID} { yyextra->current->name = yytext;
1297
1299
1300 if ((yyextra->current_root) &&
1301 (yyextra->current_root->section.isClass() ||
1302 yyextra->current_root->section.isNamespace()))
1303 {
1304 yyextra->current->name= yyextra->current_root->name + "::" + yyextra->current->name;
1305 }
1306 yyextra->modifiers[yyextra->current_root][yyextra->current->name.lower().str()].returnName = std::move(returnName);
1307
1309 {
1311 yyextra->current_root->name,
"$interface$",
QCString(yytext).lower());
1312 }
1313
1314 BEGIN(Parameterlist);
1315 }
1316<Parameterlist>"(" { yyextra->current->args = "("; }
1317<Parameterlist>")" {
1318 yyextra->current->args += ")";
1321 startScope(yyscanner,yyextra->last_entry.get());
1322 BEGIN(SubprogBody);
1323 }
QCString removeRedundantWhiteSpace(const QCString &s)
1324<Parameterlist>{COMMA}|{BS} { yyextra->current->args += yytext;
1326 if (c)
1327 {
1328 if (!yyextra->current->argList.empty())
1329 {
1330 yyextra->current->argList.back().docs = c->
str;
1331 }
1332 }
1333 }
1334<Parameterlist>{ID} {
1335
1337
1338 yyextra->current->args += param;
1342 yyextra->current->argList.push_back(arg);
1343 }
1344<Parameterlist>{NOARGS} {
1346
1348 startScope(yyscanner,yyextra->last_entry.get());
1349 BEGIN(SubprogBody);
1350 }
1351<SubprogBody>result{BS}\({BS}{ID} {
1352 if (yyextra->functionLine)
1353 {
1357 yyextra->modifiers[yyextra->current_root->parent()][yyextra->current_root->name.lower().str()].returnName = result;
1358 }
1359
1360 }
1361
1362
1363
1364<FVariable,SubprogBody,ModuleBody,TypedefBody,TypedefBodyContains>"!<" { /* backward docu comment */
1366 {
1367 yyextra->current->docLine = yyextra->lineNr;
1368 yyextra->docBlockJavaStyle =
FALSE;
1369 yyextra->docBlock.clear();
1372 yy_push_state(DocBackLine,yyscanner);
1373 }
1374 else
1375 {
1376
1377 if (YY_START == String)
1378 {
1379 yyextra->colNr -= (int)yyleng;
1380 REJECT;
1381 }
1382
1383
1384 if ((YY_START != StrIgnore) && (YY_START != String))
1385 {
1386 yy_push_state(YY_START,yyscanner);
1387 BEGIN(StrIgnore);
1388 yyextra->debugStr="*!";
1389 }
1390 }
1391 }
static void startCommentBlock(yyscan_t yyscanner, bool)
1392<DocBackLine>.* { // contents of yyextra->current comment line
1393 yyextra->docBlock+=yytext;
1394 }
1395<DocBackLine>"\n"{BS}"!"("<"|"!"+) { // comment block (next line is also comment line)
1396 yyextra->docBlock+="\n";
1398 }
1399<DocBackLine>"\n" { // comment block ends at the end of this line
1400
1401 yyextra->colNr -= 1;
1402 unput(*yytext);
1404 {
1405 std::shared_ptr<Entry> tmp_entry = yyextra->current;
1406
1407 if (yyextra->last_enum)
1408 {
1409 yyextra->current = yyextra->last_enum;
1410 }
1411 else
1412 {
1413 yyextra->current = yyextra->last_entry;
1414 }
1416
1417 yyextra->current = std::move(tmp_entry);
1418 }
1420 {
1422 }
1423 else if (yyextra->vtype ==
V_RESULT)
1424 {
1426 }
1428 yyextra->docBlock.clear();
1429 }
1430
1431<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,FEnum>^{BS} {
1433 }
static int computeIndent(const char *s)
1434<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,FEnum>"!>" {
1435 yy_push_state(YY_START,yyscanner);
1436 yyextra->current->docLine = yyextra->lineNr;
1437 yyextra->docBlockJavaStyle =
FALSE;
1438 if (YY_START==SubprogBody) yyextra->docBlockInBody =
TRUE;
1439 yyextra->docBlock.clear();
1442 BEGIN(DocBlock);
1443
1444 }
1445
1446
1447<DocBlock>({CMD}{CMD}){ID}/[^a-z_A-Z0-9] { // escaped command
1448 yyextra->docBlock += yytext;
1449 }
1450<DocBlock>{CMD}("f$"|"f["|"f{"|"f(") {
1451 yyextra->docBlock += yytext;
1452 yyextra->docBlockName=&yytext[1];
1453 if (yyextra->docBlockName.at(1)=='[')
1454 {
1455 yyextra->docBlockName.at(1)=']';
1456 }
1457 if (yyextra->docBlockName.at(1)=='{')
1458 {
1459 yyextra->docBlockName.at(1)='}';
1460 }
1461 if (yyextra->docBlockName.at(1)=='(')
1462 {
1463 yyextra->docBlockName.at(1)=')';
1464 }
1465 yyextra->fencedSize=0;
1467 BEGIN(DocCopyBlock);
1468 }
1469<DocBlock>{CMD}"ifile"{B}+"\""[^\n\"]+"\"" {
1470 yyextra->fileName = &yytext[6];
1471 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1472 yyextra->fileName = yyextra->fileName.mid(1,yyextra->fileName.length()-2);
1473 yyextra->docBlock += yytext;
1474 }
1475<DocBlock>{CMD}"ifile"{B}+{FILEMASK} {
1476 yyextra->fileName = &yytext[6];
1477 yyextra->fileName = yyextra->fileName.stripWhiteSpace();
1478 yyextra->docBlock += yytext;
1479 }
1480<DocBlock>{CMD}"iline"{LINENR}/[\n\.] |
1481<DocBlock>{CMD}"iline"{LINENR}{B} {
1482 bool ok = false;
1484 if (!ok)
1485 {
1486 warn(yyextra->fileName,yyextra->lineNr,
"Invalid line number '{}' for iline command",yytext);
1487 }
1488 else
1489 {
1490 yyextra->lineNr = nr;
1491 }
1492 yyextra->docBlock += yytext;
1493 }
int toInt(bool *ok=nullptr, int base=10) const
1494<DocBlock>{B}*"<"{PRE}">" {
1495 yyextra->docBlock += yytext;
1496 yyextra->docBlockName="<pre>";
1497 yyextra->fencedSize=0;
1499 BEGIN(DocCopyBlock);
1500 }
1501<DocBlock>{B}*"<"<CODE>">" {
1502 yyextra->docBlock += yytext;
1503 yyextra->docBlockName="<code>";
1504 yyextra->fencedSize=0;
1506 BEGIN(DocCopyBlock);
1507 }
1508<DocBlock>{CMD}"startuml"/[^a-z_A-Z0-9\-] { // verbatim command
1509 yyextra->docBlock += yytext;
1510 yyextra->docBlockName="uml";
1511 yyextra->fencedSize=0;
1513 BEGIN(DocCopyBlock);
1514 }
1515<DocBlock>{CMD}("verbatim"|"iliteral"|"latexonly"|"htmlonly"|"xmlonly"|"manonly"|"rtfonly"|"docbookonly"|"dot"|"msc"|"code")/[^a-z_A-Z0-9\-] { // verbatim command
1516 yyextra->docBlock += yytext;
1517 yyextra->docBlockName=&yytext[1];
1518 yyextra->fencedSize=0;
1520 BEGIN(DocCopyBlock);
1521 }
1522<DocBlock>"~~~"[~]* {
1524 yyextra->docBlock += pat;
1525 yyextra->docBlockName="~~~";
1526 yyextra->fencedSize=pat.
length();
1528 BEGIN(DocCopyBlock);
1529 }
1530<DocBlock>"```"[`]*/(".")?[a-zA-Z0-9#_-]+ |
1531<DocBlock>"```"[`]*/"{"[^}]+"}" |
1532<DocBlock>"```"[`]* {
1534 yyextra->docBlock += pat;
1535 yyextra->docBlockName="```";
1536 yyextra->fencedSize=pat.
length();
1538 BEGIN(DocCopyBlock);
1539 }
1540<DocBlock>"\\ilinebr "{BS} {
1542 int extraSpaces = std::max(0,static_cast<int>(yyleng-9-yyextra->curIndent-2));
1543 indent.
fill(
' ',extraSpaces);
1544
1545 yyextra->docBlock += "\\ilinebr ";
1546 yyextra->docBlock += indent;
1547 }
QCString fill(char c, int len=-1)
Fills a string with a predefined character.
1548
1549<DocBlock>[^@*`~\/\\\n]+ { // any character that isn't special
1550 yyextra->docBlock += yytext;
1551 }
1552<DocBlock>"\n"{BS}"!"(">"|"!"+) { // comment block (next line is also comment line)
1553 yyextra->docBlock+="\n";
1555 }
1556<DocBlock>"\n" { // comment block ends at the end of this line
1557
1558 yyextra->colNr -= 1;
1559 unput(*yytext);
1562 }
1563<DocBlock>. { // command block
1564 yyextra->docBlock += *yytext;
1565 }
1566
1567
1568
1569<DocCopyBlock>"</"{PRE}">" { // end of a <pre> block
1570 yyextra->docBlock += yytext;
1571 if (yyextra->docBlockName=="<pre>")
1572 {
1573 yyextra->docBlockName="";
1575 BEGIN(DocBlock);
1576 }
1577 }
1578<DocCopyBlock>"</"{CODE}">" { // end of a <code> block
1579 yyextra->docBlock += yytext;
1580 if (yyextra->docBlockName=="<code>")
1581 {
1582 yyextra->docBlockName="";
1584 BEGIN(DocBlock);
1585 }
1586 }
1587<DocCopyBlock>{CMD}("f$"|"f]"|"f}"|"f)") {
1588 yyextra->docBlock += yytext;
1589 if (yyextra->docBlockName==&yytext[1])
1590 {
1591 yyextra->docBlockName="";
1593 BEGIN(DocBlock);
1594 }
1595 }
1596<DocCopyBlock>{CMD}("endverbatim"|"endiliteral"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endmanonly"|"endrtfonly"|"enddot"|"endmsc"|"enduml"|"endcode")/[^a-z_A-Z0-9] { // end of verbatim block
1597 yyextra->docBlock += yytext;
1598 if (&yytext[4]==yyextra->docBlockName)
1599 {
1600 yyextra->docBlockName="";
1602 BEGIN(DocBlock);
1603 }
1604 }
1605
1606<DocCopyBlock>^{B}*{COMM} { // start of a comment line
1607 if (yyextra->docBlockName=="verbatim")
1608 {
1609 REJECT;
1610 }
1611 else
1612 {
1615 yyextra->docBlock += indent;
1616 }
1617 }
1618<DocCopyBlock>"~~~"[~]* {
1620 yyextra->docBlock += pat;
1621 if (yyextra->docBlockName ==
"~~~" && yyextra->fencedSize==pat.
length())
1622 {
1624 BEGIN(DocBlock);
1625 }
1626 }
1627<DocCopyBlock>"```"[`]* {
1629 yyextra->docBlock += pat;
1630 if (yyextra->docBlockName ==
"```" && yyextra->fencedSize==pat.
length())
1631 {
1633 BEGIN(DocBlock);
1634 }
1635 }
1636
1637<DocCopyBlock>[^<@/\*\]!`~"\$\\\n]+ { // any character that is not special
1638 yyextra->docBlock += yytext;
1639 }
1640<DocCopyBlock>\n { // newline
1641 yyextra->docBlock += *yytext;
1643 }
1644<DocCopyBlock>. { // any other character
1645 yyextra->docBlock += *yytext;
1646 }
1647
1648
1649<Prototype>{BS}{SUBPROG}{BS_} {
1650 BEGIN(PrototypeSubprog);
1651 }
1652<Prototype,PrototypeSubprog>{BS}{SCOPENAME}?{BS}{ID} {
1655 BEGIN(PrototypeArgs);
1656 }
1657<PrototypeArgs>{
1658"("|")"|","|{BS_} { yyextra->current->args += yytext; }
1659{ID} { yyextra->current->args += yytext;
1662 yyextra->current->argList.push_back(a);
1663 }
1664}
1665
1666
1667
1668<*>"\n" {
1670
1671 yyextra->debugStr="";
1672 }
1673
1674
1675
1676
1677<*><<EOF>> {
1678 if (yyextra->parsingPrototype)
1679 {
1681 }
1682 else if ( yyextra->includeStackPtr <= 0 )
1683 {
1684 if (YY_START!=INITIAL && YY_START!=Start)
1685 {
1686 DBG_CTX((stderr,
"==== Error: EOF reached in wrong state (end missing)"));
1688 }
1690 }
1691 else
1692 {
1694 }
1695 }
static void popBuffer(yyscan_t yyscanner)
1696<*>{LOG_OPER} { // Fortran logical comparison keywords
1697 }
1698<*>. {
1699
1700
1701 }
1702
1703
1704
1705
1706%%