{"id":258,"library":"pycparser","title":"pycparser","description":"pycparser is a complete, standards-compliant C99 parser written in pure Python, producing an Abstract Syntax Tree (AST) that can be traversed, modified, and re-emitted as C code. Current version is 3.0, released January 2026, which replaced the bundled PLY (Lex/Yacc) backend with a hand-written lexer and recursive-descent parser—eliminating all external dependencies and improving parse speed by ~30%. Release cadence is irregular; major versions are rare (2.x spanned 2012–2025).","status":"active","version":"3.0","language":"python","source_language":"en","source_url":"https://github.com/eliben/pycparser","tags":["c","parser","ast","compiler","static-analysis","cffi","code-generation"],"install":[{"cmd":"pip install pycparser","lang":"bash","label":"Latest (3.x, no-dependency)"},{"cmd":"pip install \"pycparser<3\"","lang":"bash","label":"Legacy PLY-based 2.x (Python 3.8+)"}],"dependencies":[],"imports":[{"note":"CParser lives in the c_parser submodule; top-level pycparser does not re-export it directly.","wrong":"from pycparser import CParser","symbol":"CParser","correct":"from pycparser import c_parser\nparser = c_parser.CParser()"},{"note":"parse_file IS exported from the top-level package and invokes cpp/gcc-E automatically.","symbol":"parse_file","correct":"from pycparser import parse_file"},{"note":"Used to emit C source from a pycparser AST; must be imported from the submodule.","symbol":"c_generator.CGenerator","correct":"from pycparser import c_generator\ngen = c_generator.CGenerator()"},{"note":"All AST node types and the NodeVisitor base class live in pycparser.c_ast.","symbol":"c_ast / NodeVisitor","correct":"from pycparser import c_ast\nclass MyVisitor(c_ast.NodeVisitor): ..."}],"quickstart":{"code":"from pycparser import c_parser, c_ast, c_generator\n\n# Direct in-memory parse — only works for preprocessor-free, self-contained C\nparser = c_parser.CParser()\n\nsrc = r\"\"\"\nint add(int a, int b) {\n    return a + b;\n}\n\"\"\"\n\nast = parser.parse(src, filename='<none>')\nast.show(attrnames=True, nodenames=True)\n\n# Regenerate C source from AST\ngen = c_generator.CGenerator()\nprint(gen.visit(ast))\n\n# Visitor pattern: collect all function names\nclass FuncDefVisitor(c_ast.NodeVisitor):\n    def visit_FuncDef(self, node):\n        print('Function:', node.decl.name)\n\nv = FuncDefVisitor()\nv.visit(ast)\n","lang":"python","description":"Parse a tiny C snippet directly with CParser (no preprocessor needed for self-contained code), then walk the AST with a visitor."},"warnings":[{"fix":"Remove all PLY-related kwargs from CParser() calls. The public AST API is unchanged; only internal constructor arguments differ.","message":"v3.0 dropped PLY entirely and rewrote the lexer/parser from scratch. CParser.__init__ kwargs lex_optimize, yacc_optimize, yacc_debug, lextab, yacctab are no longer accepted — passing them raises TypeError.","severity":"breaking","affected_versions":"<3.0"},{"fix":"Upgrade to Python 3.10+. Pin pycparser<3 if you must support Python 3.8 or 3.9.","message":"Python 3.8 support was dropped in v3.0. Requires Python >=3.10.","severity":"breaking","affected_versions":"3.0+"},{"fix":"Use parse_file(..., use_cpp=True) which calls cpp/gcc-E automatically, or manually preprocess with subprocess before calling parser.parse().","message":"pycparser cannot parse raw C files that contain #include or macros — it requires preprocessed input. Passing unpreprocessed C to parser.parse() will produce parse errors for any non-trivial real-world file.","severity":"gotcha","affected_versions":"all"},{"fix":"Install the companion package `pip install pycparser-fake-libc` and use `import pycparser_fake_libc; cpp_args='-I' + pycparser_fake_libc.directory`, or vendor the headers from the GitHub source tree.","message":"fake_libc_include headers are NOT included in the PyPI pip wheel. Code that assumes pycparser.__file__ contains a utils/fake_libc_include directory will fail at runtime.","severity":"gotcha","affected_versions":"all"},{"fix":"Omit -std=c99 from cpp_args when using fake_libc_include, or use a preprocessor invocation that defaults to C11 or later.","message":"The fake_libc_include headers target C11 and will cause errors if the preprocessor is invoked with -std=c99 or older standards.","severity":"gotcha","affected_versions":"2.22+"},{"fix":"Pass cpp_args=['-D__attribute__(x)=', '-D__extension__=', ...] to strip extensions before parsing, as shown in the project FAQ.","message":"pycparser supports C99 and a subset of C11, but does NOT support GCC/Clang extensions (__attribute__, __extension__, __builtin_*, etc.) out of the box. Passing GCC-extended code will raise ParseError.","severity":"gotcha","affected_versions":"all"},{"fix":"Check for updated hooks in your freezer tool. As a workaround, pin pycparser<3 until the packager adds support.","message":"Frozen-app packagers (cx_Freeze, PyInstaller) may fail to import pycparser 3.0 due to internal relative-import restructuring introduced when PLY was removed, raising ImportError on 'c_parser'.","severity":"gotcha","affected_versions":"3.0"}],"env_vars":null,"last_verified":"2026-05-12T12:25:00.164Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Install the package using pip: `pip install pycparser`","cause":"The `pycparser` package is not installed in the Python environment being used.","error":"ModuleNotFoundError: No module named 'pycparser'"},{"fix":"Update your code to remove any direct imports of `pycparser.plyparser`. If a dependency requires it, ensure that dependency is compatible with `pycparser` 3.0 or downgrade `pycparser` to a 2.x version if necessary.","cause":"In `pycparser` version 3.0, the internal `plyparser` module was removed as part of replacing the PLY backend with a hand-written parser. Code attempting to import this module will fail.","error":"ModuleNotFoundError: No module named 'pycparser.plyparser'"},{"fix":"Ensure the C code is fully preprocessed (e.g., using `gcc -E` or `clang -E`) before parsing with `pycparser`. If using standard library headers, provide `pycparser` with its bundled `fake_libc_include` directory (e.g., `parse_file('file.c', parse_headers=True, cpp_args=['-Iutils/fake_libc_include'])`). Simplify or remove non-standard C constructs if `pycparser` doesn't support them.","cause":"`pycparser` encountered C code it could not parse, often due to non-standard C extensions (like GCC built-ins), complex macros, or if the input C code was not fully preprocessed before being passed to `pycparser`.","error":"pycparser.ParseError: <file>:<line>:<column>: before: <token>"},{"fix":"Downgrade `pycparser` to a version prior to 3.0 (e.g., `pip install pycparser<3`). Alternatively, check for updates to `pycparser` or the freezing tool that address this specific compatibility problem.","cause":"This issue typically arises with `pycparser` 3.0, particularly in frozen applications (e.g., those built with `cx_Freeze`), indicating a potential circular import or an initialization problem specific to the packaging process.","error":"ImportError: cannot import name 'c_parser' from partially initialized module 'pycparser'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"cli_name":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.2,"disk_size":"18.9M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.6,"disk_size":"18.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":2.2,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.6,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.7,"disk_size":"20.9M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":3.1,"disk_size":"20.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.7,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":3.1,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.6,"disk_size":"12.7M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3,"disk_size":"11.9M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.6,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.8,"disk_size":"12.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":3.2,"disk_size":"11.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.6,"disk_size":"13M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":2.1,"disk_size":"18.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.1,"disk_size":"18.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":2.1,"disk_size":"19M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.1,"disk_size":"19M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}