CodeSampleX

Beispiel

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.

Verifiziertes Beispiel für pypi pycparser 2.22: Parse C99 source declarations into a FileAST hierarchy, manage typedef scoping with isolated state per…

sha256:ca8c63c9274039bc589c4047477b862d3c00b249d31002ec1a7aa378052c6b3b

Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen. Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen. MIT-0

Ausführungsbelege

Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.

Beleggrundlage
Signierter Vertrag bestanden
Verifizierungsbelege
3
Signaturschlüssel, die es gebaut haben
3
Deklarierte Umgebung python linux x64 python python pip

Umgebungen der Verifizierungsläufe

Umgebung Contract Stufen Lauf
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

Fall

HOW
Ziel
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.
Pakete
Symbole
  • pycparser.c_parser.CParser.parse
Umgebung
python
Erstellt
2026-08-17T23:06:18Z

Contract

  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.

Dateien

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

Quellartefakt herunterladen (tar.gz)

Quelltext

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.")

Ursprungs-Seeder

csx-seed