mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	 345cd37abe
			
		
	
	
		345cd37abe
		
			
		
	
	
	
	
		
			
			The original tool wasn't working right and it was simpler to create a new one, partially re-using some of the old code. At this point the tool runs properly on the master. (Try: ./python Tools/c-analyzer/c-analyzer.py analyze.) It take ~40 seconds on my machine to analyze the full CPython code base. Note that we'll need to iron out some OS-specific stuff (e.g. preprocessor). We're okay though since this tool isn't used yet in our workflow. We will also need to verify the analysis results in detail before activating the check in CI, though I'm pretty sure it's close. https://bugs.python.org/issue36876
		
			
				
	
	
		
			244 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
 | |
| f'''
 | |
|     struct {ANON_IDENTIFIER};
 | |
|     struct {{ ... }}
 | |
|     struct {IDENTIFIER} {{ ... }}
 | |
| 
 | |
|     union {ANON_IDENTIFIER};
 | |
|     union {{ ... }}
 | |
|     union {IDENTIFIER} {{ ... }}
 | |
| 
 | |
|     enum {ANON_IDENTIFIER};
 | |
|     enum {{ ... }}
 | |
|     enum {IDENTIFIER} {{ ... }}
 | |
| 
 | |
|     typedef {VARTYPE} {IDENTIFIER};
 | |
|     typedef {IDENTIFIER};
 | |
|     typedef {IDENTIFIER};
 | |
|     typedef {IDENTIFIER};
 | |
| '''
 | |
| 
 | |
| 
 | |
| def parse(srclines):
 | |
|     if isinstance(srclines, str):  # a filename
 | |
|         raise NotImplementedError
 | |
| 
 | |
|     
 | |
| 
 | |
| # This only handles at most 10 nested levels.
 | |
| #MATCHED_PARENS = textwrap.dedent(rf'''
 | |
| #    # matched parens
 | |
| #    (?:
 | |
| #        [(]  # level 0
 | |
| #        (?:
 | |
| #            [^()]*
 | |
| #            [(]  # level 1
 | |
| #            (?:
 | |
| #                [^()]*
 | |
| #                [(]  # level 2
 | |
| #                (?:
 | |
| #                    [^()]*
 | |
| #                    [(]  # level 3
 | |
| #                    (?:
 | |
| #                        [^()]*
 | |
| #                        [(]  # level 4
 | |
| #                        (?:
 | |
| #                            [^()]*
 | |
| #                            [(]  # level 5
 | |
| #                            (?:
 | |
| #                                [^()]*
 | |
| #                                [(]  # level 6
 | |
| #                                (?:
 | |
| #                                    [^()]*
 | |
| #                                    [(]  # level 7
 | |
| #                                    (?:
 | |
| #                                        [^()]*
 | |
| #                                        [(]  # level 8
 | |
| #                                        (?:
 | |
| #                                            [^()]*
 | |
| #                                            [(]  # level 9
 | |
| #                                            (?:
 | |
| #                                                [^()]*
 | |
| #                                                [(]  # level 10
 | |
| #                                                [^()]*
 | |
| #                                                [)]
 | |
| #                                             )*
 | |
| #                                            [^()]*
 | |
| #                                            [)]
 | |
| #                                         )*
 | |
| #                                        [^()]*
 | |
| #                                        [)]
 | |
| #                                     )*
 | |
| #                                    [^()]*
 | |
| #                                    [)]
 | |
| #                                 )*
 | |
| #                                [^()]*
 | |
| #                                [)]
 | |
| #                             )*
 | |
| #                            [^()]*
 | |
| #                            [)]
 | |
| #                         )*
 | |
| #                        [^()]*
 | |
| #                        [)]
 | |
| #                     )*
 | |
| #                    [^()]*
 | |
| #                    [)]
 | |
| #                 )*
 | |
| #                [^()]*
 | |
| #                [)]
 | |
| #             )*
 | |
| #            [^()]*
 | |
| #            [)]
 | |
| #         )*
 | |
| #        [^()]*
 | |
| #        [)]
 | |
| #     )
 | |
| #    # end matched parens
 | |
| #    ''')
 | |
| 
 | |
| '''
 | |
|         # for loop
 | |
|         (?:
 | |
|             \s* \b for
 | |
|             \s* [(]
 | |
|             (
 | |
|                 [^;]* ;
 | |
|                 [^;]* ;
 | |
|                 .*?
 | |
|              )  # <header>
 | |
|             [)]
 | |
|             \s*
 | |
|             (?:
 | |
|                 (?:
 | |
|                     (
 | |
|                         {_ind(SIMPLE_STMT, 6)}
 | |
|                      )  # <stmt>
 | |
|                     ;
 | |
|                  )
 | |
|                 |
 | |
|                 ( {{ )  # <open>
 | |
|              )
 | |
|          )
 | |
|         |
 | |
| 
 | |
| 
 | |
| 
 | |
|             (
 | |
|                 (?:
 | |
|                     (?:
 | |
|                         (?:
 | |
|                             {_ind(SIMPLE_STMT, 6)}
 | |
|                          )?
 | |
|                         return \b \s*
 | |
|                         {_ind(INITIALIZER, 5)}
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         (?:
 | |
|                             {IDENTIFIER} \s*
 | |
|                             (?: . | -> ) \s*
 | |
|                          )*
 | |
|                         {IDENTIFIER}
 | |
|                         \s* = \s*
 | |
|                         {_ind(INITIALIZER, 5)}
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         {_ind(SIMPLE_STMT, 5)}
 | |
|                      )
 | |
|                  )
 | |
|                 |
 | |
|                 # cast compound literal
 | |
|                 (?:
 | |
|                     (?:
 | |
|                         [^'"{{}};]*
 | |
|                         {_ind(STRING_LITERAL, 5)}
 | |
|                      )*
 | |
|                     [^'"{{}};]*?
 | |
|                     [^'"{{}};=]
 | |
|                     =
 | |
|                     \s* [(] [^)]* [)]
 | |
|                     \s* {{ [^;]* }}
 | |
|                  )
 | |
|              )  # <stmt>
 | |
| 
 | |
| 
 | |
| 
 | |
|         # compound statement
 | |
|         (?:
 | |
|             (
 | |
|                 (?:
 | |
| 
 | |
|                     # "for" statements are handled separately above.
 | |
|                     (?: (?: else \s+ )? if | switch | while ) \s*
 | |
|                     {_ind(COMPOUND_HEAD, 5)}
 | |
|                  )
 | |
|                 |
 | |
|                 (?: else | do )
 | |
|                 # We do not worry about compound statements for labels,
 | |
|                 # "case", or "default".
 | |
|              )?  # <header>
 | |
|             \s*
 | |
|             ( {{ )  # <open>
 | |
|          )
 | |
| 
 | |
| 
 | |
| 
 | |
|             (
 | |
|                 (?:
 | |
|                     [^'"{{}};]*
 | |
|                     {_ind(STRING_LITERAL, 5)}
 | |
|                  )*
 | |
|                 [^'"{{}};]*
 | |
|                 # Presumably we will not see "== {{".
 | |
|                 [^\s='"{{}};]
 | |
|              )?  # <header>
 | |
| 
 | |
| 
 | |
| 
 | |
|             (
 | |
|                 \b
 | |
|                 (?:
 | |
|                     # We don't worry about labels with a compound statement.
 | |
|                     (?:
 | |
|                         switch \s* [(] [^{{]* [)]
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         case \b \s* [^:]+ [:]
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         default \s* [:]
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         do
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         while \s* [(] [^{{]* [)]
 | |
|                      )
 | |
|                     |
 | |
|                     #(?:
 | |
|                     #    for \s* [(] [^{{]* [)]
 | |
|                     # )
 | |
|                     #|
 | |
|                     (?:
 | |
|                         if \s* [(]
 | |
|                         (?: [^{{]* [^)] \s* {{ )* [^{{]*
 | |
|                         [)]
 | |
|                      )
 | |
|                     |
 | |
|                     (?:
 | |
|                         else
 | |
|                         (?:
 | |
|                             \s*
 | |
|                             if \s* [(]
 | |
|                             (?: [^{{]* [^)] \s* {{ )* [^{{]*
 | |
|                             [)]
 | |
|                          )?
 | |
|                      )
 | |
|                  )
 | |
|              )?  # <header>
 | |
| '''
 |