1 2f''' 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 22def 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''' 245