1  
       2  f'''
       3      struct {ANON_IDENTIFIER};
       4      struct {{ ... }}
       5      struct {IDENTIFIER} {{ ... }}
       6  
       7      union {ANON_IDENTIFIER};
       8      union {{ ... }}
       9      union {IDENTIFIER} {{ ... }}
      10  
      11      enum {ANON_IDENTIFIER};
      12      enum {{ ... }}
      13      enum {IDENTIFIER} {{ ... }}
      14  
      15      typedef {VARTYPE} {IDENTIFIER};
      16      typedef {IDENTIFIER};
      17      typedef {IDENTIFIER};
      18      typedef {IDENTIFIER};
      19  '''
      20  
      21  
      22  def parse(srclines):
      23      if isinstance(srclines, str):  # a filename
      24          raise NotImplementedError
      25  
      26  
      27  
      28  # This only handles at most 10 nested levels.
      29  #MATCHED_PARENS = textwrap.dedent(rf'''
      30  #    # matched parens
      31  #    (?:
      32  #        [(]  # level 0
      33  #        (?:
      34  #            [^()]*
      35  #            [(]  # level 1
      36  #            (?:
      37  #                [^()]*
      38  #                [(]  # level 2
      39  #                (?:
      40  #                    [^()]*
      41  #                    [(]  # level 3
      42  #                    (?:
      43  #                        [^()]*
      44  #                        [(]  # level 4
      45  #                        (?:
      46  #                            [^()]*
      47  #                            [(]  # level 5
      48  #                            (?:
      49  #                                [^()]*
      50  #                                [(]  # level 6
      51  #                                (?:
      52  #                                    [^()]*
      53  #                                    [(]  # level 7
      54  #                                    (?:
      55  #                                        [^()]*
      56  #                                        [(]  # level 8
      57  #                                        (?:
      58  #                                            [^()]*
      59  #                                            [(]  # level 9
      60  #                                            (?:
      61  #                                                [^()]*
      62  #                                                [(]  # level 10
      63  #                                                [^()]*
      64  #                                                [)]
      65  #                                             )*
      66  #                                            [^()]*
      67  #                                            [)]
      68  #                                         )*
      69  #                                        [^()]*
      70  #                                        [)]
      71  #                                     )*
      72  #                                    [^()]*
      73  #                                    [)]
      74  #                                 )*
      75  #                                [^()]*
      76  #                                [)]
      77  #                             )*
      78  #                            [^()]*
      79  #                            [)]
      80  #                         )*
      81  #                        [^()]*
      82  #                        [)]
      83  #                     )*
      84  #                    [^()]*
      85  #                    [)]
      86  #                 )*
      87  #                [^()]*
      88  #                [)]
      89  #             )*
      90  #            [^()]*
      91  #            [)]
      92  #         )*
      93  #        [^()]*
      94  #        [)]
      95  #     )
      96  #    # end matched parens
      97  #    ''')
      98  
      99  '''
     100          # for loop
     101          (?:
     102              \s* \b for
     103              \s* [(]
     104              (
     105                  [^;]* ;
     106                  [^;]* ;
     107                  .*?
     108               )  # <header>
     109              [)]
     110              \s*
     111              (?:
     112                  (?:
     113                      (
     114                          {_ind(SIMPLE_STMT, 6)}
     115                       )  # <stmt>
     116                      ;
     117                   )
     118                  |
     119                  ( {{ )  # <open>
     120               )
     121           )
     122          |
     123  
     124  
     125  
     126              (
     127                  (?:
     128                      (?:
     129                          (?:
     130                              {_ind(SIMPLE_STMT, 6)}
     131                           )?
     132                          return \b \s*
     133                          {_ind(INITIALIZER, 5)}
     134                       )
     135                      |
     136                      (?:
     137                          (?:
     138                              {IDENTIFIER} \s*
     139                              (?: . | -> ) \s*
     140                           )*
     141                          {IDENTIFIER}
     142                          \s* = \s*
     143                          {_ind(INITIALIZER, 5)}
     144                       )
     145                      |
     146                      (?:
     147                          {_ind(SIMPLE_STMT, 5)}
     148                       )
     149                   )
     150                  |
     151                  # cast compound literal
     152                  (?:
     153                      (?:
     154                          [^'"{{}};]*
     155                          {_ind(STRING_LITERAL, 5)}
     156                       )*
     157                      [^'"{{}};]*?
     158                      [^'"{{}};=]
     159                      =
     160                      \s* [(] [^)]* [)]
     161                      \s* {{ [^;]* }}
     162                   )
     163               )  # <stmt>
     164  
     165  
     166  
     167          # compound statement
     168          (?:
     169              (
     170                  (?:
     171  
     172                      # "for" statements are handled separately above.
     173                      (?: (?: else \s+ )? if | switch | while ) \s*
     174                      {_ind(COMPOUND_HEAD, 5)}
     175                   )
     176                  |
     177                  (?: else | do )
     178                  # We do not worry about compound statements for labels,
     179                  # "case", or "default".
     180               )?  # <header>
     181              \s*
     182              ( {{ )  # <open>
     183           )
     184  
     185  
     186  
     187              (
     188                  (?:
     189                      [^'"{{}};]*
     190                      {_ind(STRING_LITERAL, 5)}
     191                   )*
     192                  [^'"{{}};]*
     193                  # Presumably we will not see "== {{".
     194                  [^\s='"{{}};]
     195               )?  # <header>
     196  
     197  
     198  
     199              (
     200                  \b
     201                  (?:
     202                      # We don't worry about labels with a compound statement.
     203                      (?:
     204                          switch \s* [(] [^{{]* [)]
     205                       )
     206                      |
     207                      (?:
     208                          case \b \s* [^:]+ [:]
     209                       )
     210                      |
     211                      (?:
     212                          default \s* [:]
     213                       )
     214                      |
     215                      (?:
     216                          do
     217                       )
     218                      |
     219                      (?:
     220                          while \s* [(] [^{{]* [)]
     221                       )
     222                      |
     223                      #(?:
     224                      #    for \s* [(] [^{{]* [)]
     225                      # )
     226                      #|
     227                      (?:
     228                          if \s* [(]
     229                          (?: [^{{]* [^)] \s* {{ )* [^{{]*
     230                          [)]
     231                       )
     232                      |
     233                      (?:
     234                          else
     235                          (?:
     236                              \s*
     237                              if \s* [(]
     238                              (?: [^{{]* [^)] \s* {{ )* [^{{]*
     239                              [)]
     240                           )?
     241                       )
     242                   )
     243               )?  # <header>
     244  '''