summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralbert-github <albert.tests@gmail.com>2018-02-17 17:32:47 (GMT)
committeralbert-github <albert.tests@gmail.com>2018-02-17 17:32:47 (GMT)
commitf5ffd481a44fa5eae225ce728d1777070c4143e1 (patch)
tree12813996e53bff4718fe51e0ff7e6d4f97d07d0d
parentb6f01ff09b17e5c2288f2418ef0a8f074456c357 (diff)
downloadDoxygen-f5ffd481a44fa5eae225ce728d1777070c4143e1.zip
Doxygen-f5ffd481a44fa5eae225ce728d1777070c4143e1.tar.gz
Doxygen-f5ffd481a44fa5eae225ce728d1777070c4143e1.tar.bz2
Implementation Fortran ENUM / ENUMERATION
All ENUMs are anonymous as they don't have a name defined in the Fortran standard.
-rw-r--r--src/fortrancode.l90
-rw-r--r--src/fortranscanner.l109
2 files changed, 153 insertions, 46 deletions
diff --git a/src/fortrancode.l b/src/fortrancode.l
index 501b492..28caef2 100644
--- a/src/fortrancode.l
+++ b/src/fortrancode.l
@@ -684,7 +684,7 @@ NUM_TYPE (complex|integer|logical|real)
LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
KIND {ARGS}
CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
-TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE)
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE|ENUMERATOR)
INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE)
@@ -695,6 +695,7 @@ FLOW (DO|SELECT|CASE|SELECT{BS}(CASE|TYPE)|WHERE|IF|THEN|ELSE|WHILE|FORALL|
COMMANDS (FORMAT|CONTAINS|MODULE{BS_}PROCEDURE|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|PRESENT|DEALLOCATE|NULLIFY|SIZE|INQUIRE|OPEN|CLOSE|FLUSH|DATA|COMMON)
IGNORE (CALL)
PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)?
+LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")"
/* | */
@@ -775,12 +776,12 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
BEGIN(Use);
}
<Use>"ONLY" { // TODO: rename
- startFontClass("keywordtype");
- codifyLines(yytext);
- endFontClass();
+ startFontClass("keywordtype");
+ codifyLines(yytext);
+ endFontClass();
yy_push_state(YY_START);
- BEGIN(UseOnly);
- }
+ BEGIN(UseOnly);
+ }
<Use>{ID} {
QCString tmp = yytext;
tmp = tmp.lower();
@@ -835,15 +836,29 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
BEGIN(ClassName);
if (!qstricmp(yytext,"module")) currentModule="module";
}
+<Start>("enum")/{BS_}|{BS}{COMMA}{BS}{LANGUAGE_BIND_SPEC}|\n { //
+ startScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ yy_push_state(YY_START);
+ BEGIN(ClassName);
+ currentClass="class";
+ }
+<*>{LANGUAGE_BIND_SPEC} { //
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
+ }
<Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n { //
- startScope();
- startFontClass("keyword");
- codifyLines(yytext);
- endFontClass();
+ startScope();
+ startFontClass("keyword");
+ codifyLines(yytext);
+ endFontClass();
yy_push_state(YY_START);
- BEGIN(ClassName);
- currentClass="class";
- }
+ BEGIN(ClassName);
+ currentClass="class";
+ }
<ClassName>{ID} {
if (currentModule == "module")
{
@@ -853,22 +868,26 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
generateLink(*g_code,yytext);
yy_pop_state();
}
-<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable deklaration
+<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable declaration
startFontClass("keyword");
g_code->codify(yytext);
endFontClass();
}
<ClassName>\n { // interface may be without name
yy_pop_state();
- YY_FTN_REJECT;
- }
+ YY_FTN_REJECT;
+ }
+<Start>^{BS}"end"({BS_}"enum").* { // just reset currentClass, rest is done in following rule
+ currentClass=0;
+ YY_FTN_REJECT;
+ }
<Start>^{BS}"end"({BS_}"type").* { // just reset currentClass, rest is done in following rule
currentClass=0;
- YY_FTN_REJECT;
+ YY_FTN_REJECT;
}
<Start>^{BS}"end"({BS_}"module").* { // just reset currentModule, rest is done in following rule
currentModule=0;
- YY_FTN_REJECT;
+ YY_FTN_REJECT;
}
/*-------- subprog definition -------------------------------------*/
<Start>({PREFIX}{BS_})?{TYPE_SPEC}{BS_}({PREFIX}{BS_})?{BS}/{SUBPROG}{BS_} { // TYPE_SPEC is for old function style function result
@@ -901,7 +920,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
yy_pop_state();
YY_FTN_RESET
}
-<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface")?{BS} { // Fortran subroutine or function ends
+<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends
//cout << "===> end function " << yytext << endl;
endScope();
startFontClass("keyword");
@@ -914,7 +933,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
generateLink(*g_code,yytext);
yy_pop_state();
}
-<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends
+<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!) { // Fortran subroutine or function ends
//cout << "===> end function " << yytext << endl;
endScope();
startFontClass("keyword");
@@ -934,7 +953,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
g_code->codify(yytext);
endFontClass();
}
-<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable deklaration
+<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable declaration
startFontClass("keywordtype");
g_code->codify(yytext);
endFontClass();
@@ -947,7 +966,7 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
endFontClass();
}
else if (g_currentMemberDef && ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString() != QCString("subroutine"))) ||
- g_currentMemberDef->isVariable()))
+ g_currentMemberDef->isVariable() || g_currentMemberDef->isEnumValue()))
{
generateLink(*g_code, yytext);
}
@@ -956,15 +975,15 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
g_code->codify(yytext);
addLocalVar(yytext);
}
- }
-<Declaration>{BS}("=>"|"="){BS} { // Procedure binding
- BEGIN(DeclarationBinding);
- g_code->codify(yytext);
- }
-<DeclarationBinding>{ID} { // Type bound procedure link
+ }
+<Declaration>{BS}("=>"|"="){BS} { // Procedure binding
+ BEGIN(DeclarationBinding);
+ g_code->codify(yytext);
+ }
+<DeclarationBinding>{ID} { // Type bound procedure link
generateLink(*g_code, yytext);
yy_pop_state();
- }
+ }
<Declaration>[(] { // start of array specification
bracketCount++;
g_code->codify(yytext);
@@ -1029,11 +1048,20 @@ PREFIX (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|I
// fixed form continuation line
YY_FTN_REJECT;
}
+ else if (QCString(yytext).stripWhiteSpace().lower() == "type")
+ {
+ yy_push_state(YY_START);
+ BEGIN(Declaration);
+ startFontClass("keywordtype");
+ g_code->codify(QCString(yytext).stripWhiteSpace());
+ endFontClass();
+ g_code->codify(yytext + 4);
+ }
else
{
- g_insideBody=TRUE;
+ g_insideBody=TRUE;
generateLink(*g_code, yytext);
- g_insideBody=FALSE;
+ g_insideBody=FALSE;
}
}
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index 85b6de9..d4a94c7 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -164,6 +164,7 @@ static Entry* global_root = 0 ;
static Entry* file_root = 0 ;
static Entry* current = 0 ;
static Entry* last_entry = 0 ;
+static Entry* last_enum = 0 ;
static ScanVar v_type = V_IGNORE; // type of parsed variable
static QList<Entry> moduleProcedures; // list of all interfaces which contain unresolved
// module procedures
@@ -198,6 +199,7 @@ static SymbolModifiers currentModifiers;
//! Holds program scope->symbol name->symbol modifiers.
static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers;
+static int anonCount = 0 ;
//-----------------------------------------------------------------------------
static int yyread(char *buf,int max_size);
@@ -226,6 +228,7 @@ static QCString extractFromParens(const QCString name);
static CommentInPrepass* locatePrepassComment(int from, int to);
static void updateVariablePrepassComment(int from, int to);
static void newLine();
+static void initEntry();
//-----------------------------------------------------------------------------
#undef YY_INPUT
@@ -260,7 +263,7 @@ NUM_TYPE (complex|integer|logical|real)
LOG_OPER (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
KIND {ARGS}
CHAR (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
-TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
+TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|ENUMERATOR|{CHAR}|TYPE{ARGS}|CLASS{ARGS}|PROCEDURE{ARGS}?)
INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
ATTR_SPEC (EXTERNAL|ALLOCATABLE|DIMENSION{ARGS}|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|NOPASS|PASS{ARGS}?|DEFERRED|NON_OVERRIDABLE|CONTIGUOUS|VOLATILE|VALUE)
@@ -297,6 +300,7 @@ SCOPENAME ({ID}{BS}"::"{BS})*
%x Variable
%x Initialization
%x ArrayInitializer
+%x Enum
%x Typedef
%x TypedefBody
%x TypedefBodyContains
@@ -711,8 +715,17 @@ private {
{ID} {
}
}
-<Start,ModuleBody,TypedefBody,SubprogBody>{
+<Start,ModuleBody,TypedefBody,SubprogBody,Enum>{
^{BS}{TYPE_SPEC}/{SEPARATE} {
+ last_enum = 0;
+ if (YY_START == Enum)
+ {
+ argType = "@"; // enum marker
+ }
+ else
+ {
+ argType = QCString(yytext).simplifyWhiteSpace().lower();
+ }
current->bodyLine = yyLineNr + 1;
current->endBodyLine = yyLineNr + lineCountPrepass;
/* variable declaration starts */
@@ -721,7 +734,6 @@ private {
addModule(NULL);
yy_push_state(ModuleBody); //anon program
}
- argType = QCString(yytext).simplifyWhiteSpace().lower();
yy_push_state(AttributeList);
}
/* Dimitri: macro expansion should already be done during preprocessing not here!
@@ -817,17 +829,30 @@ private {
modifiers[current_root][name.lower()] |= currentModifiers;
argName= name;
- v_type= V_IGNORE;
- if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC)
- { // new variable entry
- v_type = V_VARIABLE;
+ v_type= V_IGNORE;
+ if (!argType.isEmpty() && current_root->section!=Entry::FUNCTION_SEC)
+ { // new variable entry
+ v_type = V_VARIABLE;
current->section = Entry::VARIABLE_SEC;
- current->name = argName;
- current->type = argType;
- current->fileName = yyFileName;
- current->bodyLine = yyLineNr; // used for source reference
+ current->name = argName;
+ current->type = argType;
+ current->fileName = yyFileName;
+ current->bodyLine = yyLineNr; // used for source reference
current->startLine = yyLineNr;
- addCurrentEntry(1);
+ if (argType == "@")
+ {
+ current_root->addSubEntry(current);
+ current = new Entry(*current);
+ // add to the scope surrounding the enum (copy!)
+ current_root->parent()->addSubEntry(current);
+ last_enum = current;
+ current = new Entry ;
+ initEntry();
+ }
+ else
+ {
+ addCurrentEntry(1);
+ }
}
else if (!argType.isEmpty())
{ // declaration of parameter list: add type for corr. parameter
@@ -963,19 +988,72 @@ private {
{
updateVariablePrepassComment(yyColNr-(int)yyleng, yyColNr);
yy_pop_state(); // end initialization
- if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ if (last_enum)
+ {
+ last_enum->initializer= initializer;
+ }
+ else
+ {
+ if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ }
}
else
initializer+=", ";
}
<Initialization>"\n"|"!" { //|
yy_pop_state(); // end initialization
- if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ if (last_enum)
+ {
+ last_enum->initializer= initializer;
+ }
+ else
+ {
+ if (v_type == V_VARIABLE) last_entry->initializer= initializer;
+ }
yyColNr -= 1;
unput(*yytext);
}
<Initialization>. { initializer+=yytext; }
+<*>{BS}"enum"{BS}","{BS}"bind"{BS}"("{BS}"c"{BS}")"{BS} {
+ if(YY_START == Start)
+ {
+ addModule(NULL);
+ yy_push_state(ModuleBody); //anon program
+ }
+
+ yy_push_state(Enum);
+ current->protection = defaultProtection;
+ typeProtection = defaultProtection;
+ typeMode = true;
+
+ current->spec |= Entry::Struct;
+ current->name.resize(0);
+ current->args.resize(0);
+ current->name.sprintf("@%d",anonCount++);
+
+ current->section = Entry::ENUM_SEC;
+ current->fileName = yyFileName;
+ current->startLine = yyLineNr;
+ current->bodyLine = yyLineNr;
+ if ((current_root) &&
+ (current_root->section == Entry::CLASS_SEC
+ || current_root->section == Entry::NAMESPACE_SEC))
+ {
+ current->name = current_root->name + "::" + current->name;
+ }
+
+ addCurrentEntry(1);
+ startScope(last_entry);
+ BEGIN( Enum ) ;
+ }
+<Enum>"end"{BS}"enum" {
+ last_entry->parent()->endBodyLine = yyLineNr;
+ if (!endScope(current_root))
+ yyterminate();
+ typeMode = false;
+ yy_pop_state();
+ }
/*------ fortran subroutine/function handling ------------------------------------------------------------*/
/* Start is initial condition */
@@ -1117,6 +1195,7 @@ private {
{
Entry *tmp_entry = current;
current = last_entry; // temporarily switch to the previous entry
+ if (last_enum) current = last_enum;
handleCommentBlock(docBlock,TRUE);
current=tmp_entry;
}
@@ -1132,7 +1211,7 @@ private {
docBlock.resize(0);
}
-<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains>"!>" {
+<Start,SubprogBody,ModuleBody,TypedefBody,InterfaceBody,ModuleBodyContains,SubprogBodyContains,TypedefBodyContains,Enum>"!>" {
yy_push_state(YY_START);
current->docLine = yyLineNr;
docBlockJavaStyle = FALSE;