Skip to content

type_bridge.generator.parser

parser

TQL schema parser with Rust core acceleration and Lark fallback.

SchemaTransformer

SchemaTransformer(entity_annotations=None, attribute_annotations=None, relation_annotations=None, role_annotations=None)

Bases: Transformer

Transform Lark parse tree into TypeBridge schema models.

Source code in type_bridge/generator/parser.py
def __init__(
    self,
    entity_annotations: dict[str, dict[str, AnnotationValue]] | None = None,
    attribute_annotations: dict[str, dict[str, AnnotationValue]] | None = None,
    relation_annotations: dict[str, dict[str, AnnotationValue]] | None = None,
    role_annotations: dict[str, dict[str, dict[str, AnnotationValue]]] | None = None,
) -> None:
    self.schema = ParsedSchema()
    self.entity_annotations = entity_annotations or {}
    self.attribute_annotations = attribute_annotations or {}
    self.relation_annotations = relation_annotations or {}
    self.role_annotations = role_annotations or {}

start

start(items)

Root rule: returns the populated schema.

Source code in type_bridge/generator/parser.py
def start(self, items: list[Any]) -> ParsedSchema:
    """Root rule: returns the populated schema."""
    self.schema.accumulate_inheritance()
    return self.schema

parse_tql_schema

parse_tql_schema(schema_content)

Parse a TQL schema string into a :class:ParsedSchema.

Uses the Rust TypeSchema parser when available for speed, falling back to the Lark-based parser otherwise. Annotations and docstrings (extracted from comments) are always applied on the Python side.

Source code in type_bridge/generator/parser.py
def parse_tql_schema(schema_content: str) -> ParsedSchema:
    """Parse a TQL schema string into a :class:`ParsedSchema`.

    Uses the Rust ``TypeSchema`` parser when available for speed, falling
    back to the Lark-based parser otherwise.  Annotations and docstrings
    (extracted from comments) are always applied on the Python side.
    """
    # Step 1: Always extract annotations from comments first
    entity_annots, attr_annots, rel_annots, role_annots = extract_annotations(schema_content)

    # Step 2: Try Rust parser
    if _RUST_SCHEMA_AVAILABLE:
        try:
            rust_schema = _RustTypeSchema.from_typeql(schema_content)  # type: ignore[union-attr]
            schema = _rust_schema_to_parsed(
                rust_schema, entity_annots, attr_annots, rel_annots, role_annots
            )
            logger.debug("Parsed schema using Rust core")

            # Step 3: If functions/structs present, supplement with Lark
            if _HAS_FUN_OR_STRUCT.search(schema_content):
                logger.debug("Schema contains functions/structs, supplementing with Lark parser")
                lark_schema = _parse_with_lark(
                    schema_content, entity_annots, attr_annots, rel_annots, role_annots
                )
                schema.functions = lark_schema.functions
                schema.structs = lark_schema.structs

            return schema
        except Exception:
            logger.warning("Rust parser failed, falling back to Lark parser", exc_info=True)

    # Step 4: Full Lark fallback
    if not _RUST_SCHEMA_AVAILABLE:
        logger.debug("Rust core not available, using Lark parser")
    return _parse_with_lark(schema_content, entity_annots, attr_annots, rel_annots, role_annots)