CodeSampleX

Ejemplo

pycparser 2.22: Parse C99 source declarations into a FileAST hierarchy, manage typedef scoping with isolated state per invocation, and track source coordinates with CParser.parse in pycparser 2.22.

Muestra verificada para pypi pycparser 2.22: Parse C99 source declarations into a FileAST hierarchy, manage typedef scoping with isolated state per…

sha256:ca8c63c9274039bc589c4047477b862d3c00b249d31002ec1a7aa378052c6b3b

Esta red ofrece una sola cosa: una muestra que compila. La ejecutó en un sandbox y guardó el recibo firmado. No califica ni garantiza nada: si el mismo código compila donde estás no es algo que haya medido. Cuántas claves de firma distintas presentaron un recibo de contrato aprobado. Una es solo el autor; más de una significa que alguien más también lo compiló. Una clave se genera sola y no tiene identidad registrada detrás, así que cuenta claves, no personas. MIT-0

Evidencia de ejecución

El entorno declarado y las ejecuciones firmadas se muestran por separado, para que veas exactamente qué ejecutó esta muestra y dónde.

Base de evidencia
Contrato firmado aprobado
Recibos de verificación
3
Claves de firma que lo compilaron
3
Entorno declarado python linux x64 python python pip

Entornos de las ejecuciones de verificación

Entorno Contrato Etapas Ejecución
python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-17
python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-18
python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104…
2026-09-08

Caso

HOW
Objetivo
Parse C99 source declarations into a FileAST hierarchy, manage typedef scoping with isolated state per invocation, and track source coordinates with CParser.parse in pycparser 2.22.
Paquetes
Símbolos
  • pycparser.c_parser.CParser.parse
Entorno
python
Creado
2026-08-17T23:06:18Z

Contrato

  1. CParser().parse parses C99 source declarations into a typed FileAST hierarchy preserving node coordinates and declaration structures.
  2. CParser().parse isolates typedef symbol table scope across successive parse calls on the same instance, raising ParseError when undeclared types are referenced.
  3. CParser().parse recognizes #line preprocessor directives and overrides source file and line coordinate attributes accordingly.
  4. CParser().parse requires preprocessed C source input, raising ParseError on unsupported preprocessor directives and raw comments.
  5. CParser().parse parses empty input strings into a FileAST instance with an empty declaration list.

Archivos

  • NOTES.md
  • csx.json
  • requirements.txt
  • test/contract.py

Descargar el artefacto de código fuente (tar.gz)

Código fuente

NOTES.md
# pycparser Behavior Notes

## Prior Solution Search

`search_known_solution` returned `REFERENCE_ONLY` pointing to sample `sha256:3c5ca6f4d0fbebc7e9f426b8ff85289533a86a2af0b05839306773534fb7b397` for `pycparser` 3.0. No existing verified sample targeted `pycparser` 2.22.

## Pinned Release

- Package: `pycparser`
- Version: `2.22`
- Manifest: `requirements.txt` (`pycparser==2.22`)

## Observed Behaviour

In `pycparser` 2.22:
- `pycparser.c_parser.CParser().parse(text, filename="...")` parses C99 source declarations into a typed `pycparser.c_ast.FileAST` tree.
- AST nodes preserve source coordinate metadata (`coord.file`, `coord.line`, `coord.column`) across typedefs, structs, and function definitions.
- The parser handles the C typedef-name ambiguity by updating its lexer scope stack during parsing. Subsequent declarations within the same input recognize previously declared typedef identifiers as `TYPEID`.
- Calling `parse()` on an existing `CParser` instance resets the parser's internal scope stack (`_scope_stack`) and lexer line numbering, preventing typedef declarations from leaking across successive parse invocations.
- `#line` preprocessor line directives are parsed and update the coordinate file and line attributes for subsequent AST nodes.
- Preprocessed C source is required: raw unhandled preprocessor directives (such as `#include`) raise `pycparser.c_parser.ParseError` with message `Directives not supported yet`, and raw C comments raise `ParseError` (e.g. `before: /`) because `CLexer` tokenizes comments as arithmetic division rather than stripping them.
- Empty input strings parse cleanly into a `FileAST` node with an empty declaration list `ext == []`.
csx.json
{"case":{"caseId":"case:sha256:714ada2391b23026743fa2ba3f86cda34e0860e50728661f5d2338c7dd3b28c7","contract":["CParser().parse parses C99 source declarations into a typed FileAST hierarchy preserving node coordinates and declaration structures.","CParser().parse isolates typedef symbol table scope across successive parse calls on the same instance, raising ParseError when undeclared types are referenced.","CParser().parse recognizes #line preprocessor directives and overrides source file and line coordinate attributes accordingly.","CParser().parse requires preprocessed C source input, raising ParseError on unsupported preprocessor directives and raw comments.","CParser().parse parses empty input strings into a FileAST instance with an empty declaration list."],"goal":"Parse C99 source declarations into a FileAST hierarchy, manage typedef scoping with isolated state per invocation, and track source coordinates with CParser.parse in pycparser 2.22.","kind":"HOW","packages":["pkg:pypi/pycparser@2.22"],"schemaVersion":1,"symbols":["pycparser.c_parser.CParser.parse"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/pycparser@2.22"],"schemaVersion":1,"symbols":["pycparser.c_parser.CParser.parse"],"verifierAdapter":"python@1"}
requirements.txt
pycparser==2.22
test/contract.py
"""
Verifies pycparser 2.22 CParser.parse behavior: AST generation, coordinate
tracking, typedef scope management and isolation across parse calls, #line
directive support, and preprocessed input requirements.
"""

from pycparser import c_ast
from pycparser.c_parser import CParser, ParseError


def test_parse_c99_ast_and_coordinates():
    parser = CParser()
    c_source = """
    typedef struct Buffer {
        char *data;
        int capacity;
    } Buffer;

    Buffer create_buffer(int capacity) {
        Buffer buf;
        buf.capacity = capacity;
        return buf;
    }
    """
    ast = parser.parse(c_source, filename="buffer.c")

    assert isinstance(ast, c_ast.FileAST), "Root node must be FileAST"
    assert len(ast.ext) == 2, f"Expected 2 top-level declarations, got {len(ast.ext)}"

    # Typedef verification
    typedef_node = ast.ext[0]
    assert isinstance(typedef_node, c_ast.Typedef)
    assert typedef_node.name == "Buffer"
    assert typedef_node.coord.file == "buffer.c"
    assert typedef_node.coord.line == 5

    struct_node = typedef_node.type.type
    assert isinstance(struct_node, c_ast.Struct)
    assert struct_node.name == "Buffer"
    assert len(struct_node.decls) == 2
    assert struct_node.decls[0].name == "data"
    assert struct_node.decls[1].name == "capacity"

    # Function definition verification
    func_node = ast.ext[1]
    assert isinstance(func_node, c_ast.FuncDef)
    assert func_node.decl.name == "create_buffer"
    assert func_node.decl.coord.file == "buffer.c"
    assert func_node.decl.coord.line == 7

    assert isinstance(func_node.decl.type, c_ast.FuncDecl)
    assert func_node.decl.type.type.type.names == ["Buffer"]

    params = func_node.decl.type.args.params
    assert len(params) == 1
    assert params[0].name == "capacity"
    assert params[0].type.type.names == ["int"]

    body_items = func_node.body.block_items
    assert len(body_items) == 3
    assert isinstance(body_items[0], c_ast.Decl)
    assert body_items[0].name == "buf"
    assert isinstance(body_items[1], c_ast.Assignment)
    assert body_items[1].op == "="
    assert isinstance(body_items[2], c_ast.Return)


def test_typedef_scoping_and_reset():
    parser = CParser()

    # First parse: define custom typedef and use it
    src1 = """
    typedef unsigned long custom_size_t;
    custom_size_t get_size(custom_size_t val) {
        return val + 1;
    }
    """
    ast1 = parser.parse(src1, filename="file1.c")
    assert isinstance(ast1, c_ast.FileAST)
    assert len(ast1.ext) == 2
    assert ast1.ext[0].name == "custom_size_t"

    # Second parse on the SAME parser instance: custom_size_t is no longer defined
    # CParser.parse() reinitializes _scope_stack per invocation
    src2 = "custom_size_t orphan_var = 100;"
    error_raised = False
    try:
        parser.parse(src2, filename="file2.c")
    except ParseError as e:
        error_raised = True
        err_msg = str(e)
        assert "file2.c:1:15: before: orphan_var" in err_msg or "file2.c:1:9: before: orphan_var" in err_msg

    assert error_raised, "Typedefs must not leak across successive parse() invocations"


def test_line_directive_coordinates():
    parser = CParser()
    c_source = """#line 120 "virtual_header.h"
    int exported_api_symbol(void);
    """
    ast = parser.parse(c_source, filename="input.c")

    assert len(ast.ext) == 1
    decl = ast.ext[0]
    assert isinstance(decl, c_ast.Decl)
    assert decl.name == "exported_api_symbol"
    assert decl.coord.file == "virtual_header.h"
    assert decl.coord.line == 120


def test_preprocessed_input_requirements():
    parser = CParser()

    # Unhandled preprocessor directives raise ParseError
    try:
        parser.parse("#include <stdint.h>\nint x;", filename="test.c")
        assert False, "Raw #include directive should raise ParseError"
    except ParseError as e:
        assert "Directives not supported yet" in str(e)

    # Raw C comments raise ParseError because CLexer tokenizes '/' instead of stripping comments
    try:
        parser.parse("/* comment */ int y;", filename="test.c")
        assert False, "Raw comments should raise ParseError"
    except ParseError as e:
        assert "before: /" in str(e)


def test_empty_input():
    parser = CParser()
    ast = parser.parse("", filename="empty.c")
    assert isinstance(ast, c_ast.FileAST)
    assert ast.ext == []


if __name__ == "__main__":
    test_parse_c99_ast_and_coordinates()
    test_typedef_scoping_and_reset()
    test_line_directive_coordinates()
    test_preprocessed_input_requirements()
    test_empty_input()
    print("Contract assertions passed.")

Seeder de origen

csx-seed