Implementation:Google deepmind Dm control Binding Generator
| Knowledge Sources | |
|---|---|
| Domains | Code Generation, Build Tools |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
BindingGenerator is the core engine that parses MuJoCo C header declarations and generates corresponding Python source files containing constants, enums, and array size information.
Description
BindingGenerator maintains dictionaries for enums, constants, typedefs, shape hints, and an index of struct field sizes. Parsing methods (parse_enums, parse_consts_typedefs, parse_hints) use pyparsing grammars defined in header_parsing.py to extract declarations from C source.
The parse_enums method handles explicit values, bitshift expressions, and implicit counting. The parse_consts_typedefs method recursively processes #ifdef/#ifndef conditional blocks by evaluating predicates against known constants. The parse_hints method extracts array shape information from mjxmacro.h X-macros, which describe the structure of MuJoCo's data arrays.
Size resolution via resolve_size and get_shape_tuple handles integers, string constants, product expressions (such as "2*mjMAXLINEPNT"), and dynamic dimensions. Code generation methods (write_consts, write_enums, write_index_dict) produce formatted Python files with auto-generated headers, namedtuple-based enum definitions, and pretty-printed size dictionaries.
Usage
Used by the autowrap CLI as the core parsing and code generation engine. Create an instance, run the parsing methods in order (enums, then constants/typedefs, then hints), and finally call the write methods to produce the output files.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/autowrap/binding_generator.py
- Lines: 1-296
Signature
class BindingGenerator:
def __init__(self, enums_dict=None, consts_dict=None,
typedefs_dict=None, hints_dict=None, index_dict=None):
def get_consts_and_enums(self):
def resolve_size(self, old_size):
def get_shape_tuple(self, old_size, squeeze=False):
def resolve_typename(self, old_ctypes_typename):
def parse_hints(self, xmacro_src):
def parse_enums(self, src):
def parse_consts_typedefs(self, src):
def recurse_into_conditionals(self, tokens):
def make_header(self, imports=()):
def write_consts(self, fname):
def write_enums(self, fname):
def write_index_dict(self, fname):
Import
from dm_control.autowrap.binding_generator import BindingGenerator
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| enums_dict | dict | No | Pre-defined enum declarations mapping {enum_name: {member_name: value}}
|
| consts_dict | dict | No | Pre-defined constants mapping {const_name: value}
|
| typedefs_dict | dict | No | Pre-defined type mappings {type_name: ctypes_typename}
|
| hints_dict | dict | No | Pre-defined shape hints {var_name: shape_tuple}
|
| index_dict | dict | No | Pre-defined index mappings {struct_name: {var_name: shape_tuple}}
|
Outputs
| Name | Type | Description |
|---|---|---|
| write_consts(fname) | file | Python source file containing constant definitions |
| write_enums(fname) | file | Python source file containing namedtuple-based enum definitions |
| write_index_dict(fname) | file | Python source file containing array size dictionaries |
Usage Examples
from dm_control.autowrap.binding_generator import BindingGenerator
from dm_control.autowrap.codegen_util import UniqueOrderedDict
import collections
# Create a generator with pre-seeded hints
hints = UniqueOrderedDict({"buffer": ("nbuffer",), "stack": ("narena",)})
consts_dict = collections.OrderedDict()
parser = BindingGenerator(consts_dict=consts_dict, hints_dict=hints)
# Phase 1: Parse enums from header source
parser.parse_enums(header_source)
# Phase 2: Parse constants and typedefs
parser.parse_consts_typedefs(header_source)
# Phase 3: Parse shape hints from mjxmacro.h
parser.parse_hints(xmacro_source)
# Generate output files
parser.write_consts("/output/constants.py")
parser.write_enums("/output/enums.py")
parser.write_index_dict("/output/sizes.py")