Fortran: allow keywords as names

Allow keywords for names of modules, programs, types, interfaces,
structures and enums.

Test case contributed by Adam Hirst, thanks.
This commit is contained in:
Colomban Wendling 2014-02-22 16:54:30 +01:00
parent e47d45eb28
commit ed1dc50062
4 changed files with 64 additions and 11 deletions

View File

@ -1610,8 +1610,11 @@ static void parseStructureStmt (tokenInfo *const token)
strcmp (vStringValue (token->string), "/") == 0)
{ /* read structure name */
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
{
name = newTokenFrom (token);
name->type = TOKEN_IDENTIFIER;
}
skipPast (token, TOKEN_OPERATOR);
}
if (name == NULL)
@ -1728,8 +1731,11 @@ static void parseDerivedTypeDef (tokenInfo *const token)
parseQualifierSpecList (token);
if (isType (token, TOKEN_DOUBLE_COLON))
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
{
token->type = TOKEN_IDENTIFIER;
makeFortranTag (token, TAG_DERIVED_TYPE);
}
ancestorPush (token);
skipToNextStatement (token);
if (isKeyword (token, KEYWORD_private) ||
@ -1777,12 +1783,8 @@ static void parseInterfaceBlock (tokenInfo *const token)
tokenInfo *name = NULL;
Assert (isKeyword (token, KEYWORD_interface));
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
{
name = newTokenFrom (token);
}
else if (isKeyword (token, KEYWORD_assignment) ||
isKeyword (token, KEYWORD_operator))
if (isKeyword (token, KEYWORD_assignment) ||
isKeyword (token, KEYWORD_operator))
{
readToken (token);
if (isType (token, TOKEN_PAREN_OPEN))
@ -1790,6 +1792,11 @@ static void parseInterfaceBlock (tokenInfo *const token)
if (isType (token, TOKEN_OPERATOR))
name = newTokenFrom (token);
}
else if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
{
name = newTokenFrom (token);
name->type = TOKEN_IDENTIFIER;
}
if (name == NULL)
{
name = newAnonTokenFrom (token, "Interface");
@ -1844,8 +1851,11 @@ static void parseEnumBlock (tokenInfo *const token)
parseKindSelector (token);
if (isType (token, TOKEN_DOUBLE_COLON))
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
{
name = newTokenFrom (token);
name->type = TOKEN_IDENTIFIER;
}
if (name == NULL)
{
name = newAnonTokenFrom (token, "Enum");
@ -2101,8 +2111,11 @@ static void parseModule (tokenInfo *const token)
{
Assert (isKeyword (token, KEYWORD_module));
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
{
token->type = TOKEN_IDENTIFIER;
makeFortranTag (token, TAG_MODULE);
}
ancestorPush (token);
skipToNextStatement (token);
parseSpecificationPart (token);
@ -2182,8 +2195,11 @@ static void parseSubprogram (tokenInfo *const token, const tagType tag)
isKeyword (token, KEYWORD_function) ||
isKeyword (token, KEYWORD_subroutine));
readToken (token);
if (isType (token, TOKEN_IDENTIFIER))
if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))
{
token->type = TOKEN_IDENTIFIER;
makeFortranTag (token, tag);
}
ancestorPush (token);
skipToNextStatement (token);
parseSpecificationPart (token);

View File

@ -158,6 +158,7 @@ test_sources = \
keyword_implicit.cs \
keyword_interface.cs \
keyword_namespace.cs \
keyword_names.f90 \
keyword_out.cs \
keyword_override.cs \
keyword_params.cs \

View File

@ -0,0 +1,28 @@
! For some reason, the Fortran standard does not prohibit this...
module Program
type Data
integer :: contents
end type Data
integer :: i
interface Program
function myFunc(arg)
!...
end function myFunc
end interface Program
contains
function MyFunc(arg)
! ...
end function MyFunc
end module Program
program Interface
use Program
! ...
end program Interface

View File

@ -0,0 +1,8 @@
# format=tagmanager
DataÌ1ÎProgramÖ0
InterfaceÌ2048Ö0
MyFuncÌ16ÎProgramÖ0
ProgramÌ256Ö0
ProgramÌ32ÎProgramÖ0
contentsÌ64ÎDataÖ0
iÌ16384ÎProgramÖ0