pycparser 2.22__tar.gz → 3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. {pycparser-2.22 → pycparser-3.0}/MANIFEST.in +0 -4
  2. pycparser-3.0/PKG-INFO +244 -0
  3. {pycparser-2.22 → pycparser-3.0}/README.rst +15 -23
  4. {pycparser-2.22 → pycparser-3.0}/examples/c-to-c.py +5 -6
  5. {pycparser-2.22 → pycparser-3.0}/examples/c_files/funky.c +0 -5
  6. {pycparser-2.22 → pycparser-3.0}/examples/c_files/hash.c +4 -4
  7. {pycparser-2.22 → pycparser-3.0}/examples/c_json.py +65 -51
  8. pycparser-3.0/examples/cdecl.py +201 -0
  9. {pycparser-2.22 → pycparser-3.0}/examples/construct_ast_from_scratch.py +23 -16
  10. pycparser-3.0/examples/dump_ast.py +32 -0
  11. {pycparser-2.22 → pycparser-3.0}/examples/explore_ast.py +20 -21
  12. {pycparser-2.22 → pycparser-3.0}/examples/func_calls.py +12 -11
  13. {pycparser-2.22 → pycparser-3.0}/examples/func_defs.py +9 -10
  14. {pycparser-2.22 → pycparser-3.0}/examples/func_defs_add_param.py +20 -19
  15. {pycparser-2.22 → pycparser-3.0}/examples/rewrite_ast.py +4 -4
  16. {pycparser-2.22 → pycparser-3.0}/examples/serialize_ast.py +9 -8
  17. pycparser-3.0/examples/using_cpp_libc.py +28 -0
  18. {pycparser-2.22 → pycparser-3.0}/examples/using_gcc_E_libc.py +11 -9
  19. pycparser-3.0/pycparser/__init__.py +99 -0
  20. {pycparser-2.22 → pycparser-3.0}/pycparser/_ast_gen.py +106 -87
  21. pycparser-3.0/pycparser/ast_transforms.py +174 -0
  22. {pycparser-2.22 → pycparser-3.0}/pycparser/c_ast.py +450 -234
  23. pycparser-3.0/pycparser/c_generator.py +573 -0
  24. pycparser-3.0/pycparser/c_lexer.py +706 -0
  25. pycparser-3.0/pycparser/c_parser.py +2376 -0
  26. pycparser-3.0/pycparser.egg-info/PKG-INFO +244 -0
  27. {pycparser-2.22 → pycparser-3.0}/pycparser.egg-info/SOURCES.txt +1 -11
  28. pycparser-3.0/pyproject.toml +38 -0
  29. pycparser-3.0/setup.py +3 -0
  30. pycparser-3.0/tests/test_c_ast.py +136 -0
  31. {pycparser-2.22 → pycparser-3.0}/tests/test_c_generator.py +196 -176
  32. pycparser-3.0/tests/test_c_lexer.py +581 -0
  33. pycparser-3.0/tests/test_c_parser.py +3747 -0
  34. {pycparser-2.22 → pycparser-3.0}/tests/test_examples.py +11 -7
  35. pycparser-3.0/tests/test_general.py +87 -0
  36. {pycparser-2.22 → pycparser-3.0}/tests/test_util.py +16 -14
  37. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/_fake_typedefs.h +14 -0
  38. pycparser-2.22/CHANGES +0 -288
  39. pycparser-2.22/PKG-INFO +0 -28
  40. pycparser-2.22/examples/cdecl.py +0 -199
  41. pycparser-2.22/examples/dump_ast.py +0 -29
  42. pycparser-2.22/examples/using_cpp_libc.py +0 -30
  43. pycparser-2.22/pycparser/__init__.py +0 -93
  44. pycparser-2.22/pycparser/_build_tables.py +0 -40
  45. pycparser-2.22/pycparser/ast_transforms.py +0 -164
  46. pycparser-2.22/pycparser/c_generator.py +0 -502
  47. pycparser-2.22/pycparser/c_lexer.py +0 -555
  48. pycparser-2.22/pycparser/c_parser.py +0 -1950
  49. pycparser-2.22/pycparser/lextab.py +0 -10
  50. pycparser-2.22/pycparser/ply/__init__.py +0 -5
  51. pycparser-2.22/pycparser/ply/cpp.py +0 -905
  52. pycparser-2.22/pycparser/ply/ctokens.py +0 -133
  53. pycparser-2.22/pycparser/ply/lex.py +0 -1099
  54. pycparser-2.22/pycparser/ply/yacc.py +0 -3494
  55. pycparser-2.22/pycparser/ply/ygen.py +0 -74
  56. pycparser-2.22/pycparser/plyparser.py +0 -133
  57. pycparser-2.22/pycparser/yacctab.py +0 -369
  58. pycparser-2.22/pycparser.egg-info/PKG-INFO +0 -28
  59. pycparser-2.22/setup.py +0 -66
  60. pycparser-2.22/tests/test_c_ast.py +0 -148
  61. pycparser-2.22/tests/test_c_lexer.py +0 -502
  62. pycparser-2.22/tests/test_c_parser.py +0 -2483
  63. pycparser-2.22/tests/test_general.py +0 -67
  64. {pycparser-2.22 → pycparser-3.0}/LICENSE +0 -0
  65. {pycparser-2.22 → pycparser-3.0}/examples/c_files/basic.c +0 -0
  66. {pycparser-2.22 → pycparser-3.0}/examples/c_files/memmgr.c +0 -0
  67. {pycparser-2.22 → pycparser-3.0}/examples/c_files/memmgr.h +0 -0
  68. {pycparser-2.22 → pycparser-3.0}/examples/c_files/pragmas.c +0 -0
  69. {pycparser-2.22 → pycparser-3.0}/examples/c_files/year.c +0 -0
  70. {pycparser-2.22 → pycparser-3.0}/pycparser/_c_ast.cfg +0 -0
  71. {pycparser-2.22 → pycparser-3.0}/pycparser.egg-info/dependency_links.txt +0 -0
  72. {pycparser-2.22 → pycparser-3.0}/pycparser.egg-info/top_level.txt +0 -0
  73. {pycparser-2.22 → pycparser-3.0}/setup.cfg +0 -0
  74. {pycparser-2.22 → pycparser-3.0}/tests/__init__.py +0 -0
  75. {pycparser-2.22 → pycparser-3.0}/tests/c_files/c11.c +0 -0
  76. {pycparser-2.22 → pycparser-3.0}/tests/c_files/cppd_with_stdio_h.c +0 -0
  77. {pycparser-2.22 → pycparser-3.0}/tests/c_files/empty.h +0 -0
  78. {pycparser-2.22 → pycparser-3.0}/tests/c_files/example_c_file.c +0 -0
  79. {pycparser-2.22 → pycparser-3.0}/tests/c_files/hdir/9/inc.h +0 -0
  80. {pycparser-2.22 → pycparser-3.0}/tests/c_files/memmgr.c +0 -0
  81. {pycparser-2.22 → pycparser-3.0}/tests/c_files/memmgr.h +0 -0
  82. {pycparser-2.22 → pycparser-3.0}/tests/c_files/memmgr_with_h.c +0 -0
  83. {pycparser-2.22 → pycparser-3.0}/tests/c_files/simplemain.c +0 -0
  84. {pycparser-2.22 → pycparser-3.0}/tests/c_files/year.c +0 -0
  85. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/X11/Intrinsic.h +0 -0
  86. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/X11/Xlib.h +0 -0
  87. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/X11/_X11_fake_defines.h +0 -0
  88. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/X11/_X11_fake_typedefs.h +0 -0
  89. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/_ansi.h +0 -0
  90. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/_fake_defines.h +0 -0
  91. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/_syslist.h +0 -0
  92. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/aio.h +0 -0
  93. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/alloca.h +0 -0
  94. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/ar.h +0 -0
  95. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/argz.h +0 -0
  96. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/arpa/inet.h +0 -0
  97. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/asm-generic/int-ll64.h +0 -0
  98. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/assert.h +0 -0
  99. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/complex.h +0 -0
  100. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/cpio.h +0 -0
  101. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/ctype.h +0 -0
  102. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/dirent.h +0 -0
  103. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/dlfcn.h +0 -0
  104. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/emmintrin.h +0 -0
  105. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/endian.h +0 -0
  106. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/envz.h +0 -0
  107. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/errno.h +0 -0
  108. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/fastmath.h +0 -0
  109. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/fcntl.h +0 -0
  110. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/features.h +0 -0
  111. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/fenv.h +0 -0
  112. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/float.h +0 -0
  113. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/fmtmsg.h +0 -0
  114. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/fnmatch.h +0 -0
  115. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/ftw.h +0 -0
  116. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/getopt.h +0 -0
  117. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/glob.h +0 -0
  118. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/grp.h +0 -0
  119. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/iconv.h +0 -0
  120. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/ieeefp.h +0 -0
  121. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/immintrin.h +0 -0
  122. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/inttypes.h +0 -0
  123. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/iso646.h +0 -0
  124. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/langinfo.h +0 -0
  125. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/libgen.h +0 -0
  126. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/libintl.h +0 -0
  127. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/limits.h +0 -0
  128. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/linux/socket.h +0 -0
  129. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/linux/version.h +0 -0
  130. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/locale.h +0 -0
  131. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/malloc.h +0 -0
  132. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/math.h +0 -0
  133. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/mir_toolkit/client_types.h +0 -0
  134. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/monetary.h +0 -0
  135. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/mqueue.h +0 -0
  136. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/ndbm.h +0 -0
  137. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/net/if.h +0 -0
  138. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/netdb.h +0 -0
  139. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/netinet/in.h +0 -0
  140. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/netinet/tcp.h +0 -0
  141. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/newlib.h +0 -0
  142. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/nl_types.h +0 -0
  143. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/openssl/err.h +0 -0
  144. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/openssl/evp.h +0 -0
  145. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/openssl/hmac.h +0 -0
  146. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/openssl/ssl.h +0 -0
  147. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/openssl/x509v3.h +0 -0
  148. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/paths.h +0 -0
  149. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/poll.h +0 -0
  150. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/process.h +0 -0
  151. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/pthread.h +0 -0
  152. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/pwd.h +0 -0
  153. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/reent.h +0 -0
  154. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/regdef.h +0 -0
  155. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/regex.h +0 -0
  156. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sched.h +0 -0
  157. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/search.h +0 -0
  158. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/semaphore.h +0 -0
  159. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/setjmp.h +0 -0
  160. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/signal.h +0 -0
  161. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/smmintrin.h +0 -0
  162. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/spawn.h +0 -0
  163. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdalign.h +0 -0
  164. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdarg.h +0 -0
  165. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdatomic.h +0 -0
  166. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdbool.h +0 -0
  167. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stddef.h +0 -0
  168. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdint.h +0 -0
  169. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdio.h +0 -0
  170. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdlib.h +0 -0
  171. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stdnoreturn.h +0 -0
  172. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/string.h +0 -0
  173. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/strings.h +0 -0
  174. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/stropts.h +0 -0
  175. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/ioctl.h +0 -0
  176. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/ipc.h +0 -0
  177. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/mman.h +0 -0
  178. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/msg.h +0 -0
  179. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/poll.h +0 -0
  180. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/resource.h +0 -0
  181. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/select.h +0 -0
  182. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/sem.h +0 -0
  183. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/shm.h +0 -0
  184. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/socket.h +0 -0
  185. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/stat.h +0 -0
  186. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/statvfs.h +0 -0
  187. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/sysctl.h +0 -0
  188. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/time.h +0 -0
  189. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/times.h +0 -0
  190. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/types.h +0 -0
  191. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/uio.h +0 -0
  192. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/un.h +0 -0
  193. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/utsname.h +0 -0
  194. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/sys/wait.h +0 -0
  195. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/syslog.h +0 -0
  196. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/tar.h +0 -0
  197. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/termios.h +0 -0
  198. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/tgmath.h +0 -0
  199. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/threads.h +0 -0
  200. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/time.h +0 -0
  201. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/trace.h +0 -0
  202. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/ulimit.h +0 -0
  203. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/unctrl.h +0 -0
  204. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/unistd.h +0 -0
  205. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/utime.h +0 -0
  206. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/utmp.h +0 -0
  207. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/utmpx.h +0 -0
  208. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/wchar.h +0 -0
  209. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/wctype.h +0 -0
  210. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/wordexp.h +0 -0
  211. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/xcb/xcb.h +0 -0
  212. {pycparser-2.22 → pycparser-3.0}/utils/fake_libc_include/zlib.h +0 -0
@@ -6,7 +6,3 @@ include README.*
6
6
  include LICENSE
7
7
  include CHANGES
8
8
  include setup.*
9
- exclude setup.pyc
10
-
11
- recursive-exclude tests yacctab.* lextab.*
12
- recursive-exclude examples yacctab.* lextab.*
pycparser-3.0/PKG-INFO ADDED
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: pycparser
3
+ Version: 3.0
4
+ Summary: C parser in Python
5
+ Author-email: Eli Bendersky <eliben@gmail.com>
6
+ Maintainer-email: Eli Bendersky <eliben@gmail.com>
7
+ License-Expression: BSD-3-Clause
8
+ Project-URL: Homepage, https://github.com/eliben/pycparser
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/x-rst
18
+ License-File: LICENSE
19
+ Dynamic: license-file
20
+
21
+ ===============
22
+ pycparser v3.00
23
+ ===============
24
+
25
+
26
+ .. image:: https://github.com/eliben/pycparser/workflows/pycparser-tests/badge.svg
27
+ :align: center
28
+ :target: https://github.com/eliben/pycparser/actions
29
+
30
+ ----
31
+
32
+ .. contents::
33
+ :backlinks: none
34
+
35
+ .. sectnum::
36
+
37
+ Introduction
38
+ ============
39
+
40
+ What is pycparser?
41
+ ------------------
42
+
43
+ **pycparser** is a parser for the C language, written in pure Python. It is a
44
+ module designed to be easily integrated into applications that need to parse
45
+ C source code.
46
+
47
+ What is it good for?
48
+ --------------------
49
+
50
+ Anything that needs C code to be parsed. The following are some uses for
51
+ **pycparser**, taken from real user reports:
52
+
53
+ * C code obfuscator
54
+ * Front-end for various specialized C compilers
55
+ * Static code checker
56
+ * Automatic unit-test discovery
57
+ * Adding specialized extensions to the C language
58
+
59
+ One of the most popular uses of **pycparser** is in the `cffi
60
+ <https://cffi.readthedocs.io/en/latest/>`_ library, which uses it to parse the
61
+ declarations of C functions and types in order to auto-generate FFIs.
62
+
63
+ **pycparser** is unique in the sense that it's written in pure Python - a very
64
+ high level language that's easy to experiment with and tweak. To people familiar
65
+ with Lex and Yacc, **pycparser**'s code will be simple to understand. It also
66
+ has no external dependencies (except for a Python interpreter), making it very
67
+ simple to install and deploy.
68
+
69
+ Which version of C does pycparser support?
70
+ ------------------------------------------
71
+
72
+ **pycparser** aims to support the full C99 language (according to the standard
73
+ ISO/IEC 9899). Some features from C11 are also supported, and patches to support
74
+ more are welcome.
75
+
76
+ **pycparser** supports very few GCC extensions, but it's fairly easy to set
77
+ things up so that it parses code with a lot of GCC-isms successfully. See the
78
+ `FAQ <https://github.com/eliben/pycparser/wiki/FAQ>`_ for more details.
79
+
80
+ What grammar does pycparser follow?
81
+ -----------------------------------
82
+
83
+ **pycparser** very closely follows the C grammar provided in Annex A of the C99
84
+ standard (ISO/IEC 9899).
85
+
86
+ How is pycparser licensed?
87
+ --------------------------
88
+
89
+ `BSD license <https://github.com/eliben/pycparser/blob/master/LICENSE>`_.
90
+
91
+ Contact details
92
+ ---------------
93
+
94
+ For reporting problems with **pycparser** or submitting feature requests, please
95
+ open an `issue <https://github.com/eliben/pycparser/issues>`_, or submit a
96
+ pull request.
97
+
98
+
99
+ Installing
100
+ ==========
101
+
102
+ Prerequisites
103
+ -------------
104
+
105
+ **pycparser** is being tested with modern versions of Python on
106
+ Linux, macOS and Windows. See `the CI dashboard <https://github.com/eliben/pycparser/actions/workflows/ci.yml>`__
107
+ for details.
108
+
109
+ **pycparser** has no external dependencies.
110
+
111
+ Installation process
112
+ --------------------
113
+
114
+ The recommended way to install **pycparser** is with ``pip``::
115
+
116
+ > pip install pycparser
117
+
118
+ Using
119
+ =====
120
+
121
+ Interaction with the C preprocessor
122
+ -----------------------------------
123
+
124
+ In order to be compilable, C code must be preprocessed by the C preprocessor -
125
+ ``cpp``. A compatible ``cpp`` handles preprocessing directives like ``#include`` and
126
+ ``#define``, removes comments, and performs other minor tasks that prepare the C
127
+ code for compilation.
128
+
129
+ For all but the most trivial snippets of C code **pycparser**, like a C
130
+ compiler, must receive preprocessed C code in order to function correctly. If
131
+ you import the top-level ``parse_file`` function from the **pycparser** package,
132
+ it will interact with ``cpp`` for you, as long as it's in your PATH, or you
133
+ provide a path to it.
134
+
135
+ Note also that you can use ``gcc -E`` or ``clang -E`` instead of ``cpp``. See
136
+ the ``using_gcc_E_libc.py`` example for more details. Windows users can download
137
+ and install a binary build of Clang for Windows `from this website
138
+ <http://llvm.org/releases/download.html>`_.
139
+
140
+ What about the standard C library headers?
141
+ ------------------------------------------
142
+
143
+ C code almost always ``#include``\s various header files from the standard C
144
+ library, like ``stdio.h``. While (with some effort) **pycparser** can be made to
145
+ parse the standard headers from any C compiler, it's much simpler to use the
146
+ provided "fake" standard includes for C11 in ``utils/fake_libc_include``. These
147
+ are standard C header files that contain only the bare necessities to allow
148
+ valid parsing of the files that use them. As a bonus, since they're minimal, it
149
+ can significantly improve the performance of parsing large C files.
150
+
151
+ The key point to understand here is that **pycparser** doesn't really care about
152
+ the semantics of types. It only needs to know whether some token encountered in
153
+ the source is a previously defined type. This is essential in order to be able
154
+ to parse C correctly.
155
+
156
+ See `this blog post
157
+ <https://eli.thegreenplace.net/2015/on-parsing-c-type-declarations-and-fake-headers>`_
158
+ for more details.
159
+
160
+ Note that the fake headers are not included in the ``pip`` package nor installed
161
+ via the package build (`#224 <https://github.com/eliben/pycparser/issues/224>`_).
162
+
163
+ Basic usage
164
+ -----------
165
+
166
+ Take a look at the |examples|_ directory of the distribution for a few examples
167
+ of using **pycparser**. These should be enough to get you started. Please note
168
+ that most realistic C code samples would require running the C preprocessor
169
+ before passing the code to **pycparser**; see the previous sections for more
170
+ details.
171
+
172
+ .. |examples| replace:: ``examples``
173
+ .. _examples: examples
174
+
175
+
176
+ Advanced usage
177
+ --------------
178
+
179
+ The public interface of **pycparser** is well documented with comments in
180
+ ``pycparser/c_parser.py``. For a detailed overview of the various AST nodes
181
+ created by the parser, see ``pycparser/_c_ast.cfg``.
182
+
183
+ There's also a `FAQ available here <https://github.com/eliben/pycparser/wiki/FAQ>`_.
184
+ In any case, you can always drop me an `email <eliben@gmail.com>`_ for help.
185
+
186
+
187
+ Modifying
188
+ =========
189
+
190
+ There are a few points to keep in mind when modifying **pycparser**:
191
+
192
+ * The code for **pycparser**'s AST nodes is automatically generated from a
193
+ configuration file - ``_c_ast.cfg``, by ``_ast_gen.py``. If you modify the AST
194
+ configuration, make sure to re-generate the code. This can be done by running
195
+ the ``_ast_gen.py`` script (from the repository root or the
196
+ ``pycparser`` directory).
197
+ * Read the docstring in the constructor of the ``CParser`` class for details
198
+ on configuration and compatibility arguments.
199
+
200
+
201
+ Package contents
202
+ ================
203
+
204
+ Once you unzip the ``pycparser`` package, you'll see the following files and
205
+ directories:
206
+
207
+ README.rst:
208
+ This README file.
209
+
210
+ LICENSE:
211
+ The pycparser license
212
+
213
+ setup.py:
214
+ Legacy installation script (build metadata lives in ``pyproject.toml``).
215
+
216
+ pyproject.toml:
217
+ Package metadata and build configuration.
218
+
219
+ examples/:
220
+ A directory with some examples of using **pycparser**
221
+
222
+ pycparser/:
223
+ The **pycparser** module source code.
224
+
225
+ tests/:
226
+ Unit tests.
227
+
228
+ utils/fake_libc_include:
229
+ Minimal standard C library include files that should allow to parse any C code.
230
+ Note that these headers now include C11 code, so they may not work when the
231
+ preprocessor is configured to an earlier C standard (like ``-std=c99``).
232
+
233
+ utils/internal/:
234
+ Internal utilities for my own use. You probably don't need them.
235
+
236
+
237
+ Contributors
238
+ ============
239
+
240
+ Some people have contributed to **pycparser** by opening issues on bugs they've
241
+ found and/or submitting patches. The list of contributors is in the CONTRIBUTORS
242
+ file in the source distribution. After **pycparser** moved to Github I stopped
243
+ updating this list because Github does a much better job at tracking
244
+ contributions.
@@ -1,5 +1,5 @@
1
1
  ===============
2
- pycparser v2.22
2
+ pycparser v3.00
3
3
  ===============
4
4
 
5
5
 
@@ -14,7 +14,6 @@ pycparser v2.22
14
14
 
15
15
  .. sectnum::
16
16
 
17
-
18
17
  Introduction
19
18
  ============
20
19
 
@@ -83,18 +82,11 @@ Installing
83
82
  Prerequisites
84
83
  -------------
85
84
 
86
- * **pycparser** was tested with Python 3.8+ on Linux, macOS and Windows.
87
-
88
- * **pycparser** has no external dependencies. The only non-stdlib library it
89
- uses is PLY, which is bundled in ``pycparser/ply``. The current PLY version is
90
- 3.10, retrieved from `<http://www.dabeaz.com/ply/>`_
85
+ **pycparser** is being tested with modern versions of Python on
86
+ Linux, macOS and Windows. See `the CI dashboard <https://github.com/eliben/pycparser/actions/workflows/ci.yml>`__
87
+ for details.
91
88
 
92
- Note that **pycparser** (and PLY) uses docstrings for grammar specifications.
93
- Python installations that strip docstrings (such as when using the Python
94
- ``-OO`` option) will fail to instantiate and use **pycparser**. You can try to
95
- work around this problem by making sure the PLY parsing tables are pre-generated
96
- in normal mode; this isn't an officially supported/tested mode of operation,
97
- though.
89
+ **pycparser** has no external dependencies.
98
90
 
99
91
  Installation process
100
92
  --------------------
@@ -110,7 +102,7 @@ Interaction with the C preprocessor
110
102
  -----------------------------------
111
103
 
112
104
  In order to be compilable, C code must be preprocessed by the C preprocessor -
113
- ``cpp``. ``cpp`` handles preprocessing directives like ``#include`` and
105
+ ``cpp``. A compatible ``cpp`` handles preprocessing directives like ``#include`` and
114
106
  ``#define``, removes comments, and performs other minor tasks that prepare the C
115
107
  code for compilation.
116
108
 
@@ -146,7 +138,7 @@ See `this blog post
146
138
  for more details.
147
139
 
148
140
  Note that the fake headers are not included in the ``pip`` package nor installed
149
- via ``setup.py`` (`#224 <https://github.com/eliben/pycparser/issues/224>`_).
141
+ via the package build (`#224 <https://github.com/eliben/pycparser/issues/224>`_).
150
142
 
151
143
  Basic usage
152
144
  -----------
@@ -180,11 +172,10 @@ There are a few points to keep in mind when modifying **pycparser**:
180
172
  * The code for **pycparser**'s AST nodes is automatically generated from a
181
173
  configuration file - ``_c_ast.cfg``, by ``_ast_gen.py``. If you modify the AST
182
174
  configuration, make sure to re-generate the code. This can be done by running
183
- the ``_build_tables.py`` script from the ``pycparser`` directory.
184
- * Make sure you understand the optimized mode of **pycparser** - for that you
185
- must read the docstring in the constructor of the ``CParser`` class. For
186
- development you should create the parser without optimizations, so that it
187
- will regenerate the Yacc and Lex tables when you change the grammar.
175
+ the ``_ast_gen.py`` script (from the repository root or the
176
+ ``pycparser`` directory).
177
+ * Read the docstring in the constructor of the ``CParser`` class for details
178
+ on configuration and compatibility arguments.
188
179
 
189
180
 
190
181
  Package contents
@@ -200,7 +191,10 @@ LICENSE:
200
191
  The pycparser license
201
192
 
202
193
  setup.py:
203
- Installation script
194
+ Legacy installation script (build metadata lives in ``pyproject.toml``).
195
+
196
+ pyproject.toml:
197
+ Package metadata and build configuration.
204
198
 
205
199
  examples/:
206
200
  A directory with some examples of using **pycparser**
@@ -228,5 +222,3 @@ found and/or submitting patches. The list of contributors is in the CONTRIBUTORS
228
222
  file in the source distribution. After **pycparser** moved to Github I stopped
229
223
  updating this list because Github does a much better job at tracking
230
224
  contributions.
231
-
232
-
@@ -1,4 +1,4 @@
1
- #------------------------------------------------------------------------------
1
+ # ------------------------------------------------------------------------------
2
2
  # pycparser: c-to-c.py
3
3
  #
4
4
  # Example of using pycparser.c_generator, serving as a simplistic translator
@@ -6,19 +6,18 @@
6
6
  #
7
7
  # Eli Bendersky [https://eli.thegreenplace.net/]
8
8
  # License: BSD
9
- #------------------------------------------------------------------------------
9
+ # ------------------------------------------------------------------------------
10
10
  import sys
11
11
 
12
12
  # This is not required if you've installed pycparser into
13
13
  # your site-packages/ with setup.py
14
- sys.path.extend(['.', '..'])
14
+ sys.path.extend([".", ".."])
15
15
 
16
16
  from pycparser import parse_file, c_generator
17
17
 
18
18
 
19
- def translate_to_c(filename):
20
- """ Simply use the c_generator module to emit a parsed AST.
21
- """
19
+ def translate_to_c(filename: str) -> None:
20
+ """Simply use the c_generator module to emit a parsed AST."""
22
21
  ast = parse_file(filename, use_cpp=True)
23
22
  generator = c_generator.CGenerator()
24
23
  print(generator.visit(ast))
@@ -12,9 +12,4 @@ int maxout_in(int paste, char** matrix)
12
12
  int main()
13
13
  {
14
14
  auto char* multi = "a multi";
15
-
16
-
17
15
  }
18
-
19
-
20
-
@@ -24,7 +24,7 @@ typedef struct tagHash
24
24
  {
25
25
  unsigned int table_size;
26
26
 
27
- Node** heads;
27
+ Node** heads;
28
28
 
29
29
  } Hash;
30
30
 
@@ -137,7 +137,7 @@ ReturnCode HashRemove(Hash* hash, const char* key)
137
137
 
138
138
  return SUCCESS;
139
139
  }
140
-
140
+
141
141
  temp2 = temp1;
142
142
  temp1 = temp1->next;
143
143
  }
@@ -187,10 +187,10 @@ void HashDestroy(Hash* hash)
187
187
  free(temp->entry);
188
188
 
189
189
  temp = temp->next;
190
-
190
+
191
191
  free(temp2);
192
192
  }
193
- }
193
+ }
194
194
 
195
195
  free(hash->heads);
196
196
  hash->heads = NULL;
@@ -1,4 +1,4 @@
1
- #------------------------------------------------------------------------------
1
+ # ------------------------------------------------------------------------------
2
2
  # pycparser: c_json.py
3
3
  #
4
4
  # by Michael White (@mypalmike)
@@ -33,39 +33,48 @@
33
33
  # ]
34
34
  # }
35
35
  # }
36
- #------------------------------------------------------------------------------
36
+ # ------------------------------------------------------------------------------
37
37
  import json
38
38
  import sys
39
39
  import re
40
+ from typing import Any, Callable, Dict, Optional, Set, TypeVar
40
41
 
41
42
  # This is not required if you've installed pycparser into
42
43
  # your site-packages/ with setup.py
43
- #
44
- sys.path.extend(['.', '..'])
44
+ sys.path.extend([".", ".."])
45
45
 
46
46
  from pycparser import parse_file, c_ast
47
- from pycparser.plyparser import Coord
47
+ from pycparser.c_parser import Coord
48
48
 
49
49
 
50
- RE_CHILD_ARRAY = re.compile(r'(.*)\[(.*)\]')
51
- RE_INTERNAL_ATTR = re.compile('__.*__')
50
+ RE_CHILD_ARRAY = re.compile(r"(.*)\[(.*)\]")
51
+ RE_INTERNAL_ATTR = re.compile("__.*__")
52
52
 
53
53
 
54
54
  class CJsonError(Exception):
55
55
  pass
56
56
 
57
57
 
58
- def memodict(fn):
59
- """ Fast memoization decorator for a function taking a single argument """
60
- class memodict(dict):
61
- def __missing__(self, key):
62
- ret = self[key] = fn(key)
63
- return ret
64
- return memodict().__getitem__
58
+ _T = TypeVar("_T")
59
+ _R = TypeVar("_R")
60
+
61
+
62
+ def memodict(fn: Callable[[_T], _R]) -> Callable[[_T], _R]:
63
+ """Fast memoization decorator for a function taking a single argument"""
64
+ cache: Dict[_T, _R] = {}
65
+
66
+ def memoized(arg: _T) -> _R:
67
+ if arg in cache:
68
+ return cache[arg]
69
+ result = fn(arg)
70
+ cache[arg] = result
71
+ return result
72
+
73
+ return memoized
65
74
 
66
75
 
67
76
  @memodict
68
- def child_attrs_of(klass):
77
+ def child_attrs_of(klass: type[c_ast.Node]) -> Set[str]:
69
78
  """
70
79
  Given a Node class, get a set of child attrs.
71
80
  Memoized to avoid highly repetitive string manipulation
@@ -76,14 +85,14 @@ def child_attrs_of(klass):
76
85
  return all_attrs - non_child_attrs
77
86
 
78
87
 
79
- def to_dict(node):
80
- """ Recursively convert an ast into dict representation. """
88
+ def to_dict(node: c_ast.Node) -> Dict[str, Any]:
89
+ """Recursively convert an ast into dict representation."""
81
90
  klass = node.__class__
82
91
 
83
- result = {}
92
+ result: Dict[str, Any] = {}
84
93
 
85
94
  # Metadata
86
- result['_nodetype'] = klass.__name__
95
+ result["_nodetype"] = klass.__name__
87
96
 
88
97
  # Local node attributes
89
98
  for attr in klass.attr_names:
@@ -91,9 +100,9 @@ def to_dict(node):
91
100
 
92
101
  # Coord object
93
102
  if node.coord:
94
- result['coord'] = str(node.coord)
103
+ result["coord"] = str(node.coord)
95
104
  else:
96
- result['coord'] = None
105
+ result["coord"] = None
97
106
 
98
107
  # Child attributes
99
108
  for child_name, child in node.children():
@@ -105,9 +114,12 @@ def to_dict(node):
105
114
  # arrays come in order, so we verify and append.
106
115
  result[array_name] = result.get(array_name, [])
107
116
  if array_index != len(result[array_name]):
108
- raise CJsonError('Internal ast error. Array {} out of order. '
109
- 'Expected index {}, got {}'.format(
110
- array_name, len(result[array_name]), array_index))
117
+ raise CJsonError(
118
+ "Internal ast error. Array {} out of order. "
119
+ "Expected index {}, got {}".format(
120
+ array_name, len(result[array_name]), array_index
121
+ )
122
+ )
111
123
  result[array_name].append(to_dict(child))
112
124
  else:
113
125
  result[child_name] = to_dict(child)
@@ -120,53 +132,55 @@ def to_dict(node):
120
132
  return result
121
133
 
122
134
 
123
- def to_json(node, **kwargs):
124
- """ Convert ast node to json string """
135
+ def to_json(node: c_ast.Node, **kwargs: Any) -> str:
136
+ """Convert ast node to json string"""
125
137
  return json.dumps(to_dict(node), **kwargs)
126
138
 
127
139
 
128
- def file_to_dict(filename):
129
- """ Load C file into dict representation of ast """
140
+ def file_to_dict(filename: str) -> Dict[str, Any]:
141
+ """Load C file into dict representation of ast"""
130
142
  ast = parse_file(filename, use_cpp=True)
131
143
  return to_dict(ast)
132
144
 
133
145
 
134
- def file_to_json(filename, **kwargs):
135
- """ Load C file into json string representation of ast """
146
+ def file_to_json(filename: str, **kwargs: Any) -> str:
147
+ """Load C file into json string representation of ast"""
136
148
  ast = parse_file(filename, use_cpp=True)
137
149
  return to_json(ast, **kwargs)
138
150
 
139
151
 
140
- def _parse_coord(coord_str):
141
- """ Parse coord string (file:line[:column]) into Coord object. """
152
+ def _parse_coord(coord_str: Optional[str]) -> Optional[Coord]:
153
+ """Parse coord string (file:line[:column]) into Coord object."""
142
154
  if coord_str is None:
143
155
  return None
144
156
 
145
- vals = coord_str.split(':')
146
- vals.extend([None] * 3)
157
+ vals = coord_str.split(":")
158
+ vals.extend(["", "", ""])
147
159
  filename, line, column = vals[:3]
148
- return Coord(filename, line, column)
160
+ line_num = int(line) if line else 0
161
+ column_num = int(column) if column else None
162
+ return Coord(filename, line_num, column_num)
149
163
 
150
164
 
151
- def _convert_to_obj(value):
165
+ def _convert_to_obj(value: Any) -> Any:
152
166
  """
153
167
  Convert an object in the dict representation into an object.
154
168
  Note: Mutually recursive with from_dict.
155
169
 
156
170
  """
157
- value_type = type(value)
158
- if value_type == dict:
159
- return from_dict(value)
160
- elif value_type == list:
161
- return [_convert_to_obj(item) for item in value]
162
- else:
163
- # String
164
- return value
171
+ match value:
172
+ case dict():
173
+ return from_dict(value)
174
+ case list():
175
+ return [_convert_to_obj(item) for item in value]
176
+ case _:
177
+ # String
178
+ return value
165
179
 
166
180
 
167
- def from_dict(node_dict):
168
- """ Recursively build an ast from dict representation """
169
- class_name = node_dict.pop('_nodetype')
181
+ def from_dict(node_dict: Dict[str, Any]) -> c_ast.Node:
182
+ """Recursively build an ast from dict representation"""
183
+ class_name = node_dict.pop("_nodetype")
170
184
 
171
185
  klass = getattr(c_ast, class_name)
172
186
 
@@ -174,7 +188,7 @@ def from_dict(node_dict):
174
188
  # to node constructors.
175
189
  objs = {}
176
190
  for key, value in node_dict.items():
177
- if key == 'coord':
191
+ if key == "coord":
178
192
  objs[key] = _parse_coord(value)
179
193
  else:
180
194
  objs[key] = _convert_to_obj(value)
@@ -184,12 +198,12 @@ def from_dict(node_dict):
184
198
  return klass(**objs)
185
199
 
186
200
 
187
- def from_json(ast_json):
188
- """ Build an ast from json string representation """
201
+ def from_json(ast_json: str) -> c_ast.Node:
202
+ """Build an ast from json string representation"""
189
203
  return from_dict(json.loads(ast_json))
190
204
 
191
205
 
192
- #------------------------------------------------------------------------------
206
+ # ------------------------------------------------------------------------------
193
207
  if __name__ == "__main__":
194
208
  if len(sys.argv) > 1:
195
209
  # Some test code...