From 219a9b1e14084d16284c909ea055b3329750c909 Mon Sep 17 00:00:00 2001
From: Vitaly Mogulian <vitaly.mogulian@gmail.com>
Date: Sat, 30 Jul 2022 21:07:14 +0400
Subject: Fortran: Fix suprious dependencies with submodules

In commit 695f0d0d3a (cmFortranParser: Parse keywords as lexical tokens,
2016-09-05, v3.7.0-rc1~150^2) we created keyword-specific variants of
the original `USE WORD other EOSTMT` production, such as
`MODULE WORD other EOSTMT` and `INTERFACE WORD other EOSTMT`.  The same
pattern was used by more keyword-specific productions in commit b5ac8b8aa7
(Fortran: Add support for submodule syntax in dependency scanning,
2016-09-05, v3.7.0-rc1~73^2~1).

The postfix part (`other`) of several keyword-specific productions is
not needed to match Fortran syntax.  See the Fortran 2018 standard,
para.4.1.4/1 on p.28, para.14.2.1/2 on pp.293-294.  The postfix is
needed only for a case of operator 'use':

    use <module-name> [, only : <list-of-vars>]

The unnecessary postfix matching from the keyword-specific productions
such as module, submodule, and interface declarations can cause spurious
module dependencies to be detected, so remove it.

Extend the test suite with examples covering the previously-broken
cases.

Fixes: #18427
---
 Source/LexerParser/cmFortranParser.cxx             | 324 +++++++++------------
 Source/LexerParser/cmFortranParser.y               |  18 +-
 Tests/FortranModules/Submodules/CMakeLists.txt     |   1 +
 Tests/FortranModules/Submodules/main.f90           |   7 +-
 .../Submodules/obfuscated_parent.f90               |  33 +++
 Tests/FortranModules/test_module_main.f90          |   2 +-
 6 files changed, 191 insertions(+), 194 deletions(-)
 create mode 100644 Tests/FortranModules/Submodules/obfuscated_parent.f90

diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index b177296..5e5cc0b 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -548,7 +548,7 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   594
+#define YYLAST   432
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  41
@@ -557,7 +557,7 @@ union yyalloc
 /* YYNRULES -- Number of rules.  */
 #define YYNRULES  64
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  127
+#define YYNSTATES  121
 
 /* YYMAXUTOK -- Last valid token kind.  */
 #define YYMAXUTOK   295
@@ -608,15 +608,15 @@ static const yytype_int8 yytranslate[] =
 
 #if YYDEBUG
 /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_int16 yyrline[] =
+static const yytype_uint8 yyrline[] =
 {
-       0,   106,   106,   106,   109,   113,   118,   127,   133,   140,
-     145,   149,   154,   166,   171,   176,   181,   186,   191,   196,
-     201,   206,   210,   214,   218,   222,   223,   228,   228,   228,
-     229,   229,   230,   230,   231,   231,   232,   232,   233,   233,
-     234,   234,   235,   235,   236,   236,   237,   237,   240,   241,
-     242,   243,   244,   245,   246,   247,   248,   249,   250,   251,
-     252,   253,   254,   255,   256
+       0,   106,   106,   106,   109,   113,   118,   123,   129,   136,
+     141,   145,   150,   162,   167,   172,   177,   182,   187,   192,
+     197,   202,   206,   210,   214,   218,   219,   224,   224,   224,
+     225,   225,   226,   226,   227,   227,   228,   228,   229,   229,
+     230,   230,   231,   231,   232,   232,   233,   233,   236,   237,
+     238,   239,   240,   241,   242,   243,   244,   245,   246,   247,
+     248,   249,   250,   251,   252
 };
 #endif
 
@@ -666,19 +666,19 @@ yysymbol_name (yysymbol_kind_t yysymbol)
    STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     -39,    21,   -39,     1,   -39,   -20,   -39,   -39,   -39,   -39,
+     -39,    21,   -39,     5,   -39,   -23,   -39,   -39,   -39,   -39,
      -39,   -39,   -39,   -39,   -39,   -39,   -39,   -39,   -39,   -39,
-     -39,   -39,   -39,   -39,   -39,   -39,   -24,   -18,    20,    -8,
-      -3,    40,   -39,    15,    16,    17,    19,    34,   -39,   -39,
-     -39,   -39,   -39,   -39,    59,   -39,   -39,   -39,   -39,   -39,
-      36,    37,    38,   -39,   -39,   -39,   -39,   -39,   -39,    77,
-     115,   130,   168,   183,   -39,   -39,   -39,   -39,   -39,   -39,
+     -39,   -39,   -39,   -39,   -39,   -39,   -25,   -19,    20,    -8,
+     -15,   -22,   -39,    -6,    14,    15,    16,    17,   -39,   -39,
+     -39,   -39,   -39,   -39,    59,    49,    51,   -39,    63,    64,
+      35,    36,    37,   -39,   -39,   -39,   -39,   -39,   -39,    74,
+     112,   127,   165,   180,   -39,   -39,   -39,   -39,   -39,   -39,
      -39,   -39,   -39,   -39,   -39,   -39,   -39,   -39,   -39,   -39,
-     -39,   -39,   -39,   221,   236,   274,   289,   -21,    26,   -39,
-     327,   342,   380,   395,   433,   448,   -39,   -39,   -39,   -39,
-     -39,   -39,   -39,   -39,   -39,    39,    41,    42,   486,   -39,
-     -39,   -39,   -39,   -39,   -39,    18,   -39,   -39,   -39,    43,
-     501,   539,   -39,   -39,   -39,   554,   -39
+     -39,   -39,   -39,   -39,   -39,   -39,   -39,   -20,    43,   -39,
+     218,   233,   271,   286,   324,   339,   -39,   -39,   -39,   -39,
+     -39,    39,    40,    41,   377,   -39,   -39,   -39,   -39,   -39,
+     -39,    46,    78,   -39,   -39,    50,   -39,   392,    79,   -39,
+     -39
 };
 
 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -690,15 +690,15 @@ static const yytype_int8 yydefact[] =
       30,    33,    32,    34,    36,    38,    42,    40,    44,    35,
       37,    39,    43,    41,    45,    46,     0,     0,     0,     0,
        0,     0,     3,     0,     0,     0,     0,     0,    46,    46,
-      46,    46,    26,    46,     0,    46,    46,     4,    46,    46,
+      46,    46,    26,    46,     0,     0,     0,     4,     0,     0,
        0,     0,     0,    46,    46,    46,    46,    46,    46,     0,
        0,     0,     0,     0,    15,    57,    56,    64,    62,    58,
       59,    60,    61,    63,    55,    48,    49,    50,    51,    52,
-      53,    54,    47,     0,     0,     0,     0,     0,     0,    46,
+      53,    54,    47,    10,    13,     9,     6,     0,     0,    46,
        0,     0,     0,     0,     0,     0,    21,    22,    23,    24,
-      14,    10,    13,     9,     6,     0,     0,     0,     0,     5,
-      16,    17,    18,    19,    20,     0,    46,    46,    11,     0,
-       0,     0,    46,     7,    12,     0,     8
+      14,     0,     0,     0,     0,     5,    16,    17,    18,    19,
+      20,     0,     0,    46,    11,     0,     7,     0,     0,    12,
+       8
 };
 
 /* YYPGOTO[NTERM-NUM].  */
@@ -720,81 +720,70 @@ static const yytype_int8 yydefgoto[] =
    number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int8 yytable[] =
 {
-      59,    60,    61,    62,    42,    63,   105,    83,    84,   106,
-      85,    86,    43,    45,    46,    90,    91,    92,    93,    94,
-      95,     2,     3,    47,     4,    49,    50,     5,     6,     7,
+      59,    60,    61,    62,    51,    63,    52,   101,    42,    43,
+     102,    53,    45,    46,    50,    90,    91,    92,    93,    94,
+      95,     2,     3,    47,     4,    49,    54,     5,     6,     7,
        8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    54,   119,    55,
-      56,   108,    57,    48,   107,    25,    26,    27,    28,    29,
-      30,    31,    64,    65,    66,    67,    51,    58,    52,    87,
-      88,    89,   115,    53,   116,   117,   122,     0,   120,   121,
-      96,    65,    66,    67,   125,    68,    69,    70,    71,    72,
+      18,    19,    20,    21,    22,    23,    24,    55,    56,    57,
+      58,   104,    83,    48,    84,    25,    26,    27,    28,    29,
+      30,    31,    64,    65,    66,    67,    85,    86,    87,    88,
+      89,   103,   111,   112,   113,   117,   115,    96,    65,    66,
+      67,   116,   120,   118,     0,    68,    69,    70,    71,    72,
       73,    74,    75,     0,    76,    77,    78,    79,    80,    81,
-       0,     0,     0,    68,    69,    70,    71,    72,    73,    74,
-      75,     0,    76,    77,    78,    79,    80,    81,    97,    65,
+      68,    69,    70,    71,    72,    73,    74,    75,     0,    76,
+      77,    78,    79,    80,    81,    97,    65,    66,    67,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      98,    65,    66,    67,     0,     0,     0,     0,    68,    69,
+      70,    71,    72,    73,    74,    75,     0,    76,    77,    78,
+      79,    80,    81,    68,    69,    70,    71,    72,    73,    74,
+      75,     0,    76,    77,    78,    79,    80,    81,    99,    65,
       66,    67,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    98,    65,    66,    67,     0,     0,     0,
+       0,     0,     0,   100,    65,    66,    67,     0,     0,     0,
        0,    68,    69,    70,    71,    72,    73,    74,    75,     0,
       76,    77,    78,    79,    80,    81,    68,    69,    70,    71,
       72,    73,    74,    75,     0,    76,    77,    78,    79,    80,
-      81,    99,    65,    66,    67,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   100,    65,    66,    67,
+      81,   105,    65,    66,    67,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   106,    65,    66,    67,
        0,     0,     0,     0,    68,    69,    70,    71,    72,    73,
       74,    75,     0,    76,    77,    78,    79,    80,    81,    68,
       69,    70,    71,    72,    73,    74,    75,     0,    76,    77,
-      78,    79,    80,    81,   101,    65,    66,    67,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   102,
+      78,    79,    80,    81,   107,    65,    66,    67,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   108,
       65,    66,    67,     0,     0,     0,     0,    68,    69,    70,
       71,    72,    73,    74,    75,     0,    76,    77,    78,    79,
       80,    81,    68,    69,    70,    71,    72,    73,    74,    75,
-       0,    76,    77,    78,    79,    80,    81,   103,    65,    66,
+       0,    76,    77,    78,    79,    80,    81,   109,    65,    66,
       67,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   104,    65,    66,    67,     0,     0,     0,     0,
+       0,     0,   110,    65,    66,    67,     0,     0,     0,     0,
       68,    69,    70,    71,    72,    73,    74,    75,     0,    76,
       77,    78,    79,    80,    81,    68,    69,    70,    71,    72,
       73,    74,    75,     0,    76,    77,    78,    79,    80,    81,
-     109,    65,    66,    67,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   110,    65,    66,    67,     0,
+     114,    65,    66,    67,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   119,    65,    66,    67,     0,
        0,     0,     0,    68,    69,    70,    71,    72,    73,    74,
       75,     0,    76,    77,    78,    79,    80,    81,    68,    69,
       70,    71,    72,    73,    74,    75,     0,    76,    77,    78,
-      79,    80,    81,   111,    65,    66,    67,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   112,    65,
-      66,    67,     0,     0,     0,     0,    68,    69,    70,    71,
-      72,    73,    74,    75,     0,    76,    77,    78,    79,    80,
-      81,    68,    69,    70,    71,    72,    73,    74,    75,     0,
-      76,    77,    78,    79,    80,    81,   113,    65,    66,    67,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   114,    65,    66,    67,     0,     0,     0,     0,    68,
-      69,    70,    71,    72,    73,    74,    75,     0,    76,    77,
-      78,    79,    80,    81,    68,    69,    70,    71,    72,    73,
-      74,    75,     0,    76,    77,    78,    79,    80,    81,   118,
-      65,    66,    67,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   123,    65,    66,    67,     0,     0,
-       0,     0,    68,    69,    70,    71,    72,    73,    74,    75,
-       0,    76,    77,    78,    79,    80,    81,    68,    69,    70,
-      71,    72,    73,    74,    75,     0,    76,    77,    78,    79,
-      80,    81,   124,    65,    66,    67,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   126,    65,    66,
-      67,     0,     0,     0,     0,    68,    69,    70,    71,    72,
-      73,    74,    75,     0,    76,    77,    78,    79,    80,    81,
-      68,    69,    70,    71,    72,    73,    74,    75,     0,    76,
-      77,    78,    79,    80,    81
+      79,    80,    81
 };
 
 static const yytype_int8 yycheck[] =
 {
-      38,    39,    40,    41,     3,    43,    27,    45,    46,    30,
-      48,    49,    32,    37,    32,    53,    54,    55,    56,    57,
-      58,     0,     1,     3,     3,    33,    29,     6,     7,     8,
+      38,    39,    40,    41,    26,    43,    28,    27,     3,    32,
+      30,    33,    37,    32,    29,    53,    54,    55,    56,    57,
+      58,     0,     1,     3,     3,    33,    32,     6,     7,     8,
        9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    32,    30,    33,
-      33,    89,    33,    33,    28,    34,    35,    36,    37,    38,
-      39,    40,     3,     4,     5,     6,    26,    33,    28,    33,
-      33,    33,    33,    33,    33,    33,    33,    -1,   116,   117,
-       3,     4,     5,     6,   122,    26,    27,    28,    29,    30,
+      19,    20,    21,    22,    23,    24,    25,    33,    33,    33,
+      33,    89,     3,    33,     3,    34,    35,    36,    37,    38,
+      39,    40,     3,     4,     5,     6,     3,     3,    33,    33,
+      33,    28,    33,    33,    33,   113,    30,     3,     4,     5,
+       6,     3,     3,    33,    -1,    26,    27,    28,    29,    30,
       31,    32,    33,    -1,    35,    36,    37,    38,    39,    40,
-      -1,    -1,    -1,    26,    27,    28,    29,    30,    31,    32,
+      26,    27,    28,    29,    30,    31,    32,    33,    -1,    35,
+      36,    37,    38,    39,    40,     3,     4,     5,     6,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+       3,     4,     5,     6,    -1,    -1,    -1,    -1,    26,    27,
+      28,    29,    30,    31,    32,    33,    -1,    35,    36,    37,
+      38,    39,    40,    26,    27,    28,    29,    30,    31,    32,
       33,    -1,    35,    36,    37,    38,    39,    40,     3,     4,
        5,     6,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,     3,     4,     5,     6,    -1,    -1,    -1,
@@ -822,28 +811,7 @@ static const yytype_int8 yycheck[] =
       -1,    -1,    -1,    26,    27,    28,    29,    30,    31,    32,
       33,    -1,    35,    36,    37,    38,    39,    40,    26,    27,
       28,    29,    30,    31,    32,    33,    -1,    35,    36,    37,
-      38,    39,    40,     3,     4,     5,     6,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,
-       5,     6,    -1,    -1,    -1,    -1,    26,    27,    28,    29,
-      30,    31,    32,    33,    -1,    35,    36,    37,    38,    39,
-      40,    26,    27,    28,    29,    30,    31,    32,    33,    -1,
-      35,    36,    37,    38,    39,    40,     3,     4,     5,     6,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,     3,     4,     5,     6,    -1,    -1,    -1,    -1,    26,
-      27,    28,    29,    30,    31,    32,    33,    -1,    35,    36,
-      37,    38,    39,    40,    26,    27,    28,    29,    30,    31,
-      32,    33,    -1,    35,    36,    37,    38,    39,    40,     3,
-       4,     5,     6,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,     3,     4,     5,     6,    -1,    -1,
-      -1,    -1,    26,    27,    28,    29,    30,    31,    32,    33,
-      -1,    35,    36,    37,    38,    39,    40,    26,    27,    28,
-      29,    30,    31,    32,    33,    -1,    35,    36,    37,    38,
-      39,    40,     3,     4,     5,     6,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,     4,     5,
-       6,    -1,    -1,    -1,    -1,    26,    27,    28,    29,    30,
-      31,    32,    33,    -1,    35,    36,    37,    38,    39,    40,
-      26,    27,    28,    29,    30,    31,    32,    33,    -1,    35,
-      36,    37,    38,    39,    40
+      38,    39,    40
 };
 
 /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
@@ -858,11 +826,11 @@ static const yytype_int8 yystos[] =
       29,    26,    28,    33,    32,    33,    33,    33,    33,    53,
       53,    53,    53,    53,     3,     4,     5,     6,    26,    27,
       28,    29,    30,    31,    32,    33,    35,    36,    37,    38,
-      39,    40,    54,    53,    53,    53,    53,    33,    33,    33,
+      39,    40,    54,     3,     3,     3,     3,    33,    33,    33,
       53,    53,    53,    53,    53,    53,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,    27,    30,    28,    53,     3,
-       3,     3,     3,     3,     3,    33,    33,    33,     3,    30,
-      53,    53,    33,     3,     3,    53,     3
+       3,    27,    30,    28,    53,     3,     3,     3,     3,     3,
+       3,    33,    33,    33,     3,    30,     3,    53,    33,     3,
+       3
 };
 
 /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
@@ -880,8 +848,8 @@ static const yytype_int8 yyr1[] =
 /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.  */
 static const yytype_int8 yyr2[] =
 {
-       0,     2,     0,     2,     2,     4,     4,     7,     9,     4,
-       4,     5,     7,     4,     4,     3,     4,     4,     4,     4,
+       0,     2,     0,     2,     2,     4,     3,     6,     8,     3,
+       3,     5,     7,     3,     4,     3,     4,     4,     4,     4,
        4,     3,     3,     3,     3,     1,     2,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     0,     2,     1,     1,
@@ -1361,19 +1329,19 @@ yydestruct (const char *yymsg,
     case YYSYMBOL_STRING: /* STRING  */
 #line 100 "cmFortranParser.y"
             { free(((*yyvaluep).string)); }
-#line 1365 "cmFortranParser.cxx"
+#line 1333 "cmFortranParser.cxx"
         break;
 
     case YYSYMBOL_WORD: /* WORD  */
 #line 100 "cmFortranParser.y"
             { free(((*yyvaluep).string)); }
-#line 1371 "cmFortranParser.cxx"
+#line 1339 "cmFortranParser.cxx"
         break;
 
     case YYSYMBOL_CPP_INCLUDE_ANGLE: /* CPP_INCLUDE_ANGLE  */
 #line 100 "cmFortranParser.y"
             { free(((*yyvaluep).string)); }
-#line 1377 "cmFortranParser.cxx"
+#line 1345 "cmFortranParser.cxx"
         break;
 
       default:
@@ -1655,7 +1623,7 @@ yyreduce:
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
   }
-#line 1659 "cmFortranParser.cxx"
+#line 1627 "cmFortranParser.cxx"
     break;
 
   case 5: /* stmt: USE WORD other EOSTMT  */
@@ -1665,77 +1633,73 @@ yyreduce:
     cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1669 "cmFortranParser.cxx"
+#line 1637 "cmFortranParser.cxx"
     break;
 
-  case 6: /* stmt: MODULE WORD other EOSTMT  */
+  case 6: /* stmt: MODULE WORD EOSTMT  */
 #line 118 "cmFortranParser.y"
-                           {
+                     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
-    if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
-        cmsysString_strcasecmp((yyvsp[-2].string), "procedure") != 0 &&
-        cmsysString_strcasecmp((yyvsp[-2].string), "subroutine") != 0) {
-      cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
-    }
-    free((yyvsp[-2].string));
+    cmFortranParser_RuleModule(parser, (yyvsp[-1].string));
+    free((yyvsp[-1].string));
   }
-#line 1683 "cmFortranParser.cxx"
+#line 1647 "cmFortranParser.cxx"
     break;
 
-  case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT  */
-#line 127 "cmFortranParser.y"
-                                                 {
+  case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD EOSTMT  */
+#line 123 "cmFortranParser.y"
+                                           {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
-    cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
-    free((yyvsp[-4].string));
-    free((yyvsp[-2].string));
+    cmFortranParser_RuleSubmodule(parser, (yyvsp[-3].string), (yyvsp[-1].string));
+    free((yyvsp[-3].string));
+    free((yyvsp[-1].string));
   }
-#line 1694 "cmFortranParser.cxx"
+#line 1658 "cmFortranParser.cxx"
     break;
 
-  case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT  */
-#line 133 "cmFortranParser.y"
-                                                            {
+  case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD EOSTMT  */
+#line 129 "cmFortranParser.y"
+                                                      {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
-    cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
-    free((yyvsp[-6].string));
-    free((yyvsp[-4].string));
-    free((yyvsp[-2].string));
+    cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-5].string), (yyvsp[-3].string), (yyvsp[-1].string));
+    free((yyvsp[-5].string));
+    free((yyvsp[-3].string));
+    free((yyvsp[-1].string));
   }
-#line 1706 "cmFortranParser.cxx"
+#line 1670 "cmFortranParser.cxx"
     break;
 
-  case 9: /* stmt: INTERFACE WORD other EOSTMT  */
-#line 140 "cmFortranParser.y"
-                              {
+  case 9: /* stmt: INTERFACE WORD EOSTMT  */
+#line 136 "cmFortranParser.y"
+                        {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
-    free((yyvsp[-2].string));
+    free((yyvsp[-1].string));
   }
-#line 1716 "cmFortranParser.cxx"
+#line 1680 "cmFortranParser.cxx"
     break;
 
-  case 10: /* stmt: END INTERFACE other EOSTMT  */
-#line 145 "cmFortranParser.y"
-                             {
+  case 10: /* stmt: END INTERFACE EOSTMT  */
+#line 141 "cmFortranParser.y"
+                       {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, false);
   }
-#line 1725 "cmFortranParser.cxx"
+#line 1689 "cmFortranParser.cxx"
     break;
 
   case 11: /* stmt: USE DCOLON WORD other EOSTMT  */
-#line 149 "cmFortranParser.y"
+#line 145 "cmFortranParser.y"
                                {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1735 "cmFortranParser.cxx"
+#line 1699 "cmFortranParser.cxx"
     break;
 
   case 12: /* stmt: USE COMMA WORD DCOLON WORD other EOSTMT  */
-#line 154 "cmFortranParser.y"
+#line 150 "cmFortranParser.y"
                                           {
     if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
       cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1748,139 +1712,139 @@ yyreduce:
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1752 "cmFortranParser.cxx"
+#line 1716 "cmFortranParser.cxx"
     break;
 
-  case 13: /* stmt: INCLUDE STRING other EOSTMT  */
-#line 166 "cmFortranParser.y"
-                              {
+  case 13: /* stmt: INCLUDE STRING EOSTMT  */
+#line 162 "cmFortranParser.y"
+                        {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
-    cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
-    free((yyvsp[-2].string));
+    cmFortranParser_RuleInclude(parser, (yyvsp[-1].string));
+    free((yyvsp[-1].string));
   }
-#line 1762 "cmFortranParser.cxx"
+#line 1726 "cmFortranParser.cxx"
     break;
 
   case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT  */
-#line 171 "cmFortranParser.y"
+#line 167 "cmFortranParser.y"
                                          {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1772 "cmFortranParser.cxx"
+#line 1736 "cmFortranParser.cxx"
     break;
 
   case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT  */
-#line 176 "cmFortranParser.y"
+#line 172 "cmFortranParser.y"
                                  {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1782 "cmFortranParser.cxx"
+#line 1746 "cmFortranParser.cxx"
     break;
 
   case 16: /* stmt: include STRING other EOSTMT  */
-#line 181 "cmFortranParser.y"
+#line 177 "cmFortranParser.y"
                               {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1792 "cmFortranParser.cxx"
+#line 1756 "cmFortranParser.cxx"
     break;
 
   case 17: /* stmt: define WORD other EOSTMT  */
-#line 186 "cmFortranParser.y"
+#line 182 "cmFortranParser.y"
                            {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1802 "cmFortranParser.cxx"
+#line 1766 "cmFortranParser.cxx"
     break;
 
   case 18: /* stmt: undef WORD other EOSTMT  */
-#line 191 "cmFortranParser.y"
+#line 187 "cmFortranParser.y"
                           {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1812 "cmFortranParser.cxx"
+#line 1776 "cmFortranParser.cxx"
     break;
 
   case 19: /* stmt: ifdef WORD other EOSTMT  */
-#line 196 "cmFortranParser.y"
+#line 192 "cmFortranParser.y"
                           {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1822 "cmFortranParser.cxx"
+#line 1786 "cmFortranParser.cxx"
     break;
 
   case 20: /* stmt: ifndef WORD other EOSTMT  */
-#line 201 "cmFortranParser.y"
+#line 197 "cmFortranParser.y"
                            {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1832 "cmFortranParser.cxx"
+#line 1796 "cmFortranParser.cxx"
     break;
 
   case 21: /* stmt: if other EOSTMT  */
-#line 206 "cmFortranParser.y"
+#line 202 "cmFortranParser.y"
                   {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIf(parser);
   }
-#line 1841 "cmFortranParser.cxx"
+#line 1805 "cmFortranParser.cxx"
     break;
 
   case 22: /* stmt: elif other EOSTMT  */
-#line 210 "cmFortranParser.y"
+#line 206 "cmFortranParser.y"
                     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleElif(parser);
   }
-#line 1850 "cmFortranParser.cxx"
+#line 1814 "cmFortranParser.cxx"
     break;
 
   case 23: /* stmt: else other EOSTMT  */
-#line 214 "cmFortranParser.y"
+#line 210 "cmFortranParser.y"
                     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleElse(parser);
   }
-#line 1859 "cmFortranParser.cxx"
+#line 1823 "cmFortranParser.cxx"
     break;
 
   case 24: /* stmt: endif other EOSTMT  */
-#line 218 "cmFortranParser.y"
+#line 214 "cmFortranParser.y"
                      {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleEndif(parser);
   }
-#line 1868 "cmFortranParser.cxx"
+#line 1832 "cmFortranParser.cxx"
     break;
 
   case 48: /* misc_code: WORD  */
-#line 240 "cmFortranParser.y"
+#line 236 "cmFortranParser.y"
                       { free ((yyvsp[0].string)); }
-#line 1874 "cmFortranParser.cxx"
+#line 1838 "cmFortranParser.cxx"
     break;
 
   case 55: /* misc_code: STRING  */
-#line 247 "cmFortranParser.y"
+#line 243 "cmFortranParser.y"
                       { free ((yyvsp[0].string)); }
-#line 1880 "cmFortranParser.cxx"
+#line 1844 "cmFortranParser.cxx"
     break;
 
 
-#line 1884 "cmFortranParser.cxx"
+#line 1848 "cmFortranParser.cxx"
 
       default: break;
     }
@@ -2104,6 +2068,6 @@ yyreturnlab:
   return yyresult;
 }
 
-#line 259 "cmFortranParser.y"
+#line 255 "cmFortranParser.y"
 
 /* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index 07ca630..a5c8976 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -115,34 +115,30 @@ stmt:
     cmFortranParser_RuleUse(parser, $2);
     free($2);
   }
-| MODULE WORD other EOSTMT {
+| MODULE WORD EOSTMT {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
-    if (cmsysString_strcasecmp($2, "function") != 0 &&
-        cmsysString_strcasecmp($2, "procedure") != 0 &&
-        cmsysString_strcasecmp($2, "subroutine") != 0) {
-      cmFortranParser_RuleModule(parser, $2);
-    }
+    cmFortranParser_RuleModule(parser, $2);
     free($2);
   }
-| SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT {
+| SUBMODULE LPAREN WORD RPAREN WORD EOSTMT {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleSubmodule(parser, $3, $5);
     free($3);
     free($5);
   }
-| SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT {
+| SUBMODULE LPAREN WORD COLON WORD RPAREN WORD EOSTMT {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleSubmoduleNested(parser, $3, $5, $7);
     free($3);
     free($5);
     free($7);
   }
-| INTERFACE WORD other EOSTMT {
+| INTERFACE WORD EOSTMT {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
     free($2);
   }
-| END INTERFACE other EOSTMT {
+| END INTERFACE EOSTMT {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, false);
   }
@@ -163,7 +159,7 @@ stmt:
     free($3);
     free($5);
   }
-| INCLUDE STRING other EOSTMT {
+| INCLUDE STRING EOSTMT {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, $2);
     free($2);
diff --git a/Tests/FortranModules/Submodules/CMakeLists.txt b/Tests/FortranModules/Submodules/CMakeLists.txt
index ab8e0f9..783af7e 100644
--- a/Tests/FortranModules/Submodules/CMakeLists.txt
+++ b/Tests/FortranModules/Submodules/CMakeLists.txt
@@ -16,6 +16,7 @@
 add_executable(submod
   main.f90
   parent.f90
+  obfuscated_parent.f90
   child.f90
   grandchild.f90
   greatgrandchild.f90
diff --git a/Tests/FortranModules/Submodules/main.f90 b/Tests/FortranModules/Submodules/main.f90
index 3cd2989..67ffba8 100644
--- a/Tests/FortranModules/Submodules/main.f90
+++ b/Tests/FortranModules/Submodules/main.f90
@@ -1,7 +1,10 @@
 program main
   use parent, only : child_function,grandchild_subroutine
   use parent, only : sibling_function,GreatGrandChild_subroutine
+  ! Using a module without postfix
+  use obfuscated_parent
   implicit none
-  if (child_function()) call grandchild_subroutine
-  if (sibling_function()) call GreatGrandChild_subroutine
+  if (child_function())     call grandchild_subroutine
+  if (sibling_function())   call GreatGrandChild_subroutine
+  if (child_function_obf()) call grandchild_subroutine_obf
 end program
diff --git a/Tests/FortranModules/Submodules/obfuscated_parent.f90 b/Tests/FortranModules/Submodules/obfuscated_parent.f90
new file mode 100644
index 0000000..f3e68be
--- /dev/null
+++ b/Tests/FortranModules/Submodules/obfuscated_parent.f90
@@ -0,0 +1,33 @@
+! This module has two procedures from the "parent" module
+! but it has different combinations 'module <word>' phrases
+! in breaked lines for test of modules dependencies detection
+
+! Module declaration on breaked line with reminder
+module &
+         obfuscated_parent;  implicit none
+
+  interface
+
+    ! Boolean module function
+    module logical &
+                     function child_function_obf() result(child_stuff)
+    end function
+
+    ! Module subroutine
+    module subroutine &
+                     grandchild_subroutine_obf()
+    end subroutine
+
+  end interface
+
+  contains
+
+    module logical function child_function_obf() result(child_stuff)
+      child_stuff=.true.
+    end function
+
+    module subroutine grandchild_subroutine_obf()
+      print *,"Test passed."
+    end subroutine
+
+end module obfuscated_parent
diff --git a/Tests/FortranModules/test_module_main.f90 b/Tests/FortranModules/test_module_main.f90
index 6ac97fa..958d0a2 100644
--- a/Tests/FortranModules/test_module_main.f90
+++ b/Tests/FortranModules/test_module_main.f90
@@ -1,4 +1,4 @@
 PROGRAM MAINF90
-  USE TEST_MODULE
+  USE TEST_MODULE, only : TEST_MODULE_FUNCTION
   PRINT *,'Sum is',TEST_MODULE_FUNCTION(1., 2.)
 END PROGRAM MAINF90
-- 
cgit v0.12