""" Base class for DSL definitions. DSLDefinition provides the interface for defining domain-specific languages that can be used with the DslEditor control and CodeMirror. """ from abc import ABC, abstractmethod from functools import cached_property from typing import List, Dict, Any from myfasthtml.core.dsl.lark_to_lezer import ( lark_to_lezer_grammar, extract_completions_from_grammar, ) from myfasthtml.core.utils import make_safe_id class DSLDefinition(ABC): """ Base class for DSL definitions. Subclasses must implement get_grammar() to provide the Lark grammar. The Lezer grammar and completions are automatically derived. Attributes: name: Human-readable name of the DSL. """ name: str = "DSL" @abstractmethod def get_grammar(self) -> str: """ Return the Lark grammar string for this DSL. Returns: The Lark grammar as a string. """ pass @cached_property def lezer_grammar(self) -> str: """ Return the Lezer grammar derived from the Lark grammar. This is cached after first computation. Returns: The Lezer grammar as a string. """ return lark_to_lezer_grammar(self.get_grammar()) @cached_property def completions(self) -> Dict[str, List[str]]: """ Return completion items extracted from the grammar. This is cached after first computation. Returns: Dictionary with completion categories: - 'keywords': Language keywords (if, not, and, etc.) - 'operators': Comparison and arithmetic operators - 'functions': Function-like constructs (style, format, etc.) - 'types': Type names (number, date, boolean, etc.) - 'literals': Literal values (True, False, etc.) """ return extract_completions_from_grammar(self.get_grammar()) def get_editor_config(self) -> Dict[str, Any]: """ Return the configuration for the DslEditor JavaScript initialization. Returns: Dictionary with: - 'lezerGrammar': The Lezer grammar string - 'completions': The completion items - 'name': The DSL name """ return { "name": self.name, "lezerGrammar": self.lezer_grammar, "completions": self.completions, } def get_id(self): return make_safe_id(self.name)