diff options
Diffstat (limited to 'src/fortranscanner.l')
-rw-r--r-- | src/fortranscanner.l | 200 |
1 files changed, 150 insertions, 50 deletions
diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 03f75d4..6fcc70a 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -87,6 +87,8 @@ struct SymbolModifiers { bool pointer; bool target; bool save; + bool deferred; + bool nonoverridable; bool nopass; bool pass; QCString passVar; @@ -94,7 +96,7 @@ struct SymbolModifiers { SymbolModifiers() : type(), returnName(), protection(NONE_P), direction(NONE_D), optional(FALSE), dimension(), allocatable(FALSE), external(FALSE), intrinsic(FALSE), parameter(FALSE), - pointer(FALSE), target(FALSE), save(FALSE), + pointer(FALSE), target(FALSE), save(FALSE), deferred(FALSE), nonoverridable(FALSE), nopass(FALSE), pass(FALSE), passVar() {} SymbolModifiers& operator|=(const SymbolModifiers &mdfs); @@ -119,6 +121,7 @@ static const char * inputString; static int inputPosition; static bool isFixedForm; static QCString inputStringPrepass; ///< Input string for prepass of line cont. '&' +static QCString inputStringSemi; ///< Input string after command separetor ';' static unsigned int inputPositionPrepass; static int lineCountPrepass = 0; @@ -195,6 +198,7 @@ static void truncatePrepass(int index); static void pushBuffer(QCString &buffer); static void popBuffer(); static void extractPrefix(QCString& text); +static QCString extractFromParens(const QCString name); //----------------------------------------------------------------------------- #undef YY_INPUT @@ -226,10 +230,10 @@ NOARGS {BS}"\n" NUM_TYPE (complex|integer|logical|real) KIND {ARGS} CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS})) -TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS_}PRECISION|{CHAR}|TYPE{ARGS}|PROCEDURE{ARGS}) +TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS_}PRECISION|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?) INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")" -ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}) +ATTR_SPEC (ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}?|DEFERRED|NON_OVERRIDABLE) ACCESS_SPEC (PRIVATE|PUBLIC) LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")" /* Assume that attribute statements are almost the same as attributes. */ @@ -263,6 +267,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA %x ArrayInitializer %x Typedef %x TypedefBody +%x TypedefBodyContains %x InterfaceBody %x StrIgnore %x String @@ -373,7 +378,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA /*------ use handling ------------------------------------------------------------*/ -<Start,ModuleBody,TypedefBody,SubprogBody>"use"{BS_} { +<Start,ModuleBody,SubprogBody>"use"{BS_} { if(YY_START == Start) { addModule(NULL); @@ -424,7 +429,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA // interface body is a scope of its own } -^{BS}interface{BS_}{ID} { ifType = IF_GENERIC; +^{BS}interface{BS_}{ID}{ARGS}? { ifType = IF_GENERIC; yy_push_state(InterfaceBody); // extract generic name @@ -473,6 +478,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA } <ModuleBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(ModuleBodyContains); } <SubprogBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(SubprogBodyContains); } +<TypedefBody>^{BS}{CONTAINS}/({BS}|\n|!) { BEGIN(TypedefBodyContains); } /*------ module handling ------------------------------------------------------------*/ <Start>module|program{BS_} { // @@ -506,48 +512,103 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA /*------- type definition -------------------------------------------------------------------------------*/ -<Start,ModuleBody>"type"({BS_}|({COMMA}{ACCESS_SPEC}|{COMMA}{LANGUAGE_BIND_SPEC})) { +<Start,ModuleBody>^{BS}type { if(YY_START == Start) { addModule(NULL); yy_push_state(ModuleBody); //anon program } - yy_push_state(Typedef); - current->protection = defaultProtection; + yy_push_state(Typedef); + current->protection = defaultProtection; } -<Typedef>{ACCESS_SPEC} { - QCString type= yytext; +<Typedef>{ +{COMMA} {} + +{BS}"::"{BS} {} + +abstract { + current->spec |= Entry::AbstractClass; } -<Typedef>{LANGUAGE_BIND_SPEC} { - /* ignored for now */ +extends{ARGS} { + QCString basename = extractFromParens(yytext); + current->extends->append(new BaseInfo(basename, Public, Normal)); } -<Typedef>{ID} { /* type name found */ - //cout << "=========> got typedef " << yytext << ": " << yyLineNr << endl; - current->section = Entry::CLASS_SEC; // was Entry::STRUCT_SEC; - current->spec = Entry::Struct; - current->name = yytext; - - /* if type is part of a module, mod name is necessary for output */ - if ((current_root) && - (current_root->section == Entry::CLASS_SEC || - current_root->section == Entry::NAMESPACE_SEC)) - //current_root->section == Entry::INTERFACE_SEC)) - { - current->name= current_root->name+"::"+current->name; - } - current->fileName = yyFileName; - current->bodyLine = yyLineNr; - addCurrentEntry(); - startScope(last_entry); - BEGIN(TypedefBody); +public { + current->protection = Public; } -<TypedefBody>^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!) { /* end type definition */ - //printf("=========> got typedef end \n"); - if (!endScope(current_root)) - yyterminate(); - yy_pop_state(); - } +private { + current->protection = Private; + } +{LANGUAGE_BIND_SPEC} { + /* ignored for now */ + } +{ID} { /* type name found */ + current->section = Entry::CLASS_SEC; + current->spec |= Entry::Struct; + current->name = yytext; + current->fileName = yyFileName; + current->bodyLine = yyLineNr; + + /* if type is part of a module, mod name is necessary for output */ + if ((current_root) && + (current_root->section == Entry::CLASS_SEC + || current_root->section == Entry::NAMESPACE_SEC)) + { + current->name = current_root->name + "::" + current->name; + } + + addCurrentEntry(); + startScope(last_entry); + BEGIN(TypedefBody); + } +} + +<TypedefBodyContains>{ /* Type Bound Procedures */ +^{BS}PROCEDURE{ARGS}? { + current->type = QCString(yytext).simplifyWhiteSpace(); + } +^{BS}final { + current->spec |= Entry::Final; + current->type = QCString(yytext).simplifyWhiteSpace(); + } +^{BS}generic { + current->type = QCString(yytext).simplifyWhiteSpace(); + } +{COMMA} { + } +{ATTR_SPEC} { + currentModifiers |= QCString(yytext); + } +{BS}"::"{BS} { + } +{ID} { + QCString name = yytext; + modifiers[current_root][name.lower()] |= currentModifiers; + current->section = Entry::FUNCTION_SEC; + current->name = name; + current->fileName = yyFileName; + current->bodyLine = yyLineNr; + addCurrentEntry(); + } +{BS}"=>"[^(\n|\!)]* { /* Specific bindings come after the ID. */ + last_entry->args = yytext; + } +"\n" { + currentModifiers = SymbolModifiers(); + yyLineNr++; yyLineNr+=lineCountPrepass; lineCountPrepass=0; + docBlock.resize(0); + } +} + + +<TypedefBody,TypedefBodyContains>{ +^{BS}"end"{BS}"type"({BS_}{ID})?{BS}/(\n|!) { /* end type definition */ + if (!endScope(current_root)) + yyterminate(); + yy_pop_state(); + } +} /*------- module/global/typedef variable ---------------------------------------------------*/ @@ -563,19 +624,16 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA if (!endScope(current_root)) yyterminate(); yy_pop_state() ; - } + } <Start,ModuleBody,TypedefBody,SubprogBody>{ -^{BS}{TYPE_SPEC}/{SEPARATE} { +^{BS}{TYPE_SPEC}/{SEPARATE} { /* variable declaration starts */ if(YY_START == Start) { addModule(NULL); yy_push_state(ModuleBody); //anon program } - //fprintf(stderr,"4=========> got variable type: %s\n",yytext); - QCString help=yytext; - help= help.simplifyWhiteSpace(); - argType= help; + argType = QCString(yytext).simplifyWhiteSpace(); yy_push_state(AttributeList); } ^{BS}{PP_ID}{KIND}? { /* check for preprocessor symbol expand to type */ @@ -616,9 +674,20 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA <AttributeList>{ {COMMA} {} {BS} {} -{ATTR_SPEC} { /* update current modifiers */ - QCString tmp = yytext; - currentModifiers |= (tmp); +{ATTR_SPEC}. { /* update current modifierswhen it is an ATTR_SPEC and not a variable name */ + /* bug_625519 */ + QChar chr = yytext[yyleng-1]; + if (chr.isLetter() || chr.isDigit() || (chr == '_')) + { + REJECT; + } + else + { + QCString tmp = yytext; + tmp = tmp.left(tmp.length() - 1); + unput(yytext[yyleng-1]); + currentModifiers |= (tmp); + } } "::" { /* end attribute list */ BEGIN( Variable ); @@ -680,6 +749,12 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA yyLineNr++; yyLineNr+=lineCountPrepass; lineCountPrepass=0; docBlock.resize(0); } +<Variable>";".*"\n" { currentModifiers = SymbolModifiers(); + yy_pop_state(); // end variable deklaration list + docBlock.resize(0); + inputStringSemi =(const char*)(yytext+1); + pushBuffer(inputStringSemi); + } <Initialization,ArrayInitializer>"(/" { initializer+=yytext; initializerArrayScope++; @@ -721,7 +796,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA <Start,ModuleBody,SubprogBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>^{BS}({PREFIX}{BS_})?{TYPE_SPEC}{BS}/{SUBPROG}{BS_} { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) { - addInterface(yytext, ifType); + addInterface("$interface$", ifType); startScope(last_entry); } @@ -823,7 +898,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA yy_pop_state(); } -<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains>"!>" { +<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains>"!>" { yy_push_state(YY_START); current->docLine = yyLineNr; docBlockJavaStyle = FALSE; @@ -1208,6 +1283,8 @@ SymbolModifiers& SymbolModifiers::operator|=(const SymbolModifiers &mdfs) pointer |= mdfs.pointer; target |= mdfs.target; save |= mdfs.save; + deferred |= mdfs.deferred; + nonoverridable |= mdfs.nonoverridable; nopass |= mdfs.nopass; pass |= mdfs.pass; passVar = mdfs.passVar; @@ -1277,10 +1354,21 @@ SymbolModifiers& SymbolModifiers::operator|=(QCString mdfString) { newMdf.nopass = TRUE; } + else if (mdfString=="deferred") + { + newMdf.deferred = TRUE; + } + else if (mdfString=="non_overridable") + { + newMdf.nonoverridable = TRUE; + } else if (mdfString.contains("pass")) { newMdf.pass = TRUE; - newMdf.passVar = extractFromParens(mdfString); + if (mdfString.contains("(")) + newMdf.passVar = extractFromParens(mdfString); + else + newMdf.passVar = ""; } (*this) |= newMdf; @@ -1388,6 +1476,16 @@ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs) typeName += ","; typeName += "save"; } + if (mdfs.deferred) + { + typeName += ","; + typeName += "deferred"; + } + if (mdfs.nonoverridable) + { + typeName += ","; + typeName += "non_overridable"; + } if (mdfs.nopass) { typeName += ","; @@ -1396,7 +1494,9 @@ static QCString applyModifiers(QCString typeName, SymbolModifiers& mdfs) if (mdfs.pass) { typeName += ","; - typeName += "pass(" + mdfs.passVar + ")"; + typeName += "pass"; + if (!mdfs.passVar.isEmpty()) + typeName += "(" + mdfs.passVar + ")"; } if (mdfs.protection == SymbolModifiers::PUBLIC) { |