summaryrefslogtreecommitdiffstats
path: root/src/fortranscanner.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/fortranscanner.l')
-rw-r--r--src/fortranscanner.l200
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)
{