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
- 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.
Archivos
- NOTES.md
- csx.json
- requirements.txt
- test/contract.py
Código fuente
# 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 == []`.
{"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"}
pycparser==2.22
"""
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.")